728x90
Expo 알림(Notification) 구현하기
📍구현 목표
- 앱 실행 시 위치 및 알림 권한 요청
- 하루에 세 번 운동 알림 보내기 (오전 10시, 오후 2시, 저녁 8시)
- (테스트용) 즉시 알림을 보내는 테스트 버튼
1. expo-notifications 설치
npx expo install expo-notifications
2. 앱 실행 시 권한 요청
시작 화면에서 권한 요청을 해야한다! 기존코드 위치 권한 아래에 알림 설정 코드를 넣었돠.
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
}),
})
const requestPermissions = async () => {
// 위치 권한 요청
const { status: notificationStatus } =
await Notifications.requestPermissionsAsync()
if (notificationStatus !== 'granted') {
Alert.alert(
'알림 권한 필요',
'운동 알림을 받으려면 알림 권한이 필요합니다.',
[{ text: '확인' }]
)
} else {
await scheduleNotifications()
}
}
useEffect(() => {
requestPermissions()
}, [])
⚠️ 알림 권한이 계속 거부되는 오류
위 코드를 작성했더니 왼쪽사진의 허용/허용 안 함의 alert가 아닌 오른쪽 사진처럼 이미 거부된 alert가 뜬다.
이 오류는 Notifications.requestPermissionsAsync()가 항상 denied 상태를 반환하는 문제로, Stack Overflow에서도 동일한 상황을 겪었던 것 같다.
Expo `Notifications.requestPermissionsAsync()` always return status denied
I’ve built a React native Expo internal android application in the apk format. I’ve setup the app and firebase for push notification correctly. But when I install the apk on an Android phone I alwa...
stackoverflow.com
🔍 원인
- 사용자가 한 번 거부한 경우, 시스템이 다시 요청하지 않을 수 있음.
- iOS에서는 설정에서 명시적으로 권한을 변경하지 않으면 다시 요청할 수 없음.
- 안드로이드에서는 앱이 권한 요청을 트리거할 수 없는 경우가 발생할 수 있음.
✅ 해결 방법
- requestPermissionsAsync()를 호출하기 전에 getPermissionsAsync()로 현재 권한 상태를 먼저 확인하자..!
-> 해도 여전히 거부 alert가 뜸...ㅠ!
- 사용자가 직접 설정 화면으로 이동해 권한을 변경할 수 있도록 안내하기
-> 위가 일시적 오류일 수도 있기 때문에 일단 두고, alert부분에서 사용자가 직접 알림 권한을 설정할 수 있도록 했돠..!
Alert.alert(
'알림 권한을 허용해주세요!',
'앱 설정에서 권한을 직접 변경해야 합니다.',
[{ text: '설정으로 이동', onPress: () => Linking.openSettings() }]
);
3. 특정 시간에 알림 보내기 (스케줄링) ⏰
매일 오전 10시, 오후 3시, 오후 8시에 알림이 반복적으로 발생하도록 설정했다! (따로 utils 폴더에 함수 분리해줌!)
import * as Notifications from 'expo-notifications'
export const scheduleNotifications = async () => {
const notificationSchedules = [
{ hour: 10, message: '🌅 굿모닝! 오늘도 헬스장 가야죠? 💪🏻' },
{ hour: 15, message: '오늘 운동을 완료했나요? 💪🏻' },
{ hour: 20, message: '오늘 운동을 완료했나요? 💪🏻' },
]
for (const { hour, message } of notificationSchedules) {
await Notifications.scheduleNotificationAsync({
content: {
title: '🏋️ 운동할 시간!',
body: message,
sound: 'default',
},
trigger: {
type: 'daily',
hour,
minute: 0,
repeats: true,
} as Notifications.DailyTriggerInput,
})
}
}
4. 알림 테스트하기
테스트용으로 즉시 알림을 보내는 함수를 만들었다. 버튼에 함수를 연결하고 테스트해보면 작동이 잘 된다!
export const testNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: '🚀 테스트 알림',
body: '테스트 알림입니다!',
sound: 'default',
},
trigger: null, // 즉시 실행
});
};
최종코드
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
}),
})
const requestPermissions = async () => {
// 알림 권한 요청
const { status: existingNotificationStatus } =
await Notifications.getPermissionsAsync()
if (existingNotificationStatus !== 'granted') {
const { status: notificationStatus } =
await Notifications.requestPermissionsAsync()
if (notificationStatus !== 'granted') {
Alert.alert(
'알림 권한 필요',
'운동 알림을 받으려면 알림 권한이 필요합니다.',
[{ text: '설정으로 이동', onPress: () => Linking.openSettings() }]
)
return
}
await scheduleNotifications()
}
}
useEffect(() => {
requestPermissions()
}, [])
'🔥React 뽀개기' 카테고리의 다른 글
React 태그 입력 기능 구현하기 (0) | 2025.03.23 |
---|---|
Expo 앱 배포하기(웹 링크 + Expo QR 코드) (2) | 2025.02.15 |
react native에 kakao map 연동하기(feat. 현재 위치 띄우기 + 키워드 검색) (2) | 2025.02.10 |
React Native에 React Query 적용하기 (0) | 2025.02.08 |
React Native와 Expo로 간편하게 앱 개발하기 (1) | 2025.02.04 |