모바일 앱을 개발하다 보면 푸시 알림 구현은 필수적인 기능 중 하나입니다.
하지만 React Native와 Expo를 사용하여 개발할 때, 푸시 알림을 구현하는 방법에는 여러 가지가 있어서 혼란스러울 수 있습니다.
특히 FCM(Firebase Cloud Messaging)과 Expo 푸시 알림 서비스의 차이점을 이해하지 못하면 백엔드 개발자와의 소통에서도 문제가 발생할 수 있습니다.
이 글에서는 FCM과 Expo 푸시 알림의 차이점, 그리고 각각의 상황에서 어떻게 구현해야 하는지 알아보겠습니다.
푸시 알림은 사용자가 앱을 실행하지 않을 때에도 중요한 정보를 전달할 수 있는 메시지입니다.
백엔드 서버에서 알림 서비스(FCM, APNS 등)를 통해 사용자 기기로 메시지를 전송합니다.
FCM(Firebase Cloud Messaging)은 Google이 제공하는 크로스 플랫폼 메시징 솔루션으로, Android, iOS, 웹 등 다양한 플랫폼에서 무료로 메시지를 안정적으로 전송할 수 있습니다.
FCM을 사용하기 위해서는 각 기기마다 고유한 "FCM 토큰"이 필요합니다.
이 토큰은 앱이 설치될 때 Firebase SDK를 통해 생성되며, 백엔드 서버에 저장되어 푸시 알림을 보낼 때 사용됩니다.
Expo는 React Native 앱 개발을 쉽게 해주는 플랫폼으로, 자체 푸시 알림 서비스를 제공합니다.
Expo 푸시 알림 서비스는 FCM, APNS(Apple Push Notification Service) 등의 기본 푸시 서비스를 추상화하여 개발자가 쉽게 사용할 수 있게 해줍니다.
Expo 푸시 알림을 사용하기 위해서는 "Expo 푸시 토큰"이 필요합니다. 이 토큰은 Notifications.getExpoPushTokenAsync()를 통해 얻을 수 있으며, 일반적으로 ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx] 형태를 가집니다.
FCM과 Expo 푸시 알림은 각각 장단점이 있으며, 프로젝트의 요구사항과 개발 환경에 따라 선택해야 합니다.
FCM 토큰:
eQ78sHGrRJyh6tgdFJGr:APA91bHx...)Expo 푸시 토큰:
ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx] 형식FCM:
Expo:
FCM:
Expo 푸시 알림:
Expo Go는 개발 단계에서 앱을 빠르게 테스트할 수 있는 환경을 제공하지만, 푸시 알림에 관해서는 몇 가지 제한사항이 있습니다:
FCM 직접 사용 불가: Expo Go에서는 FCM을 직접 사용할 수 없습니다. @react-native-firebase/messaging과 같은 패키지를 설치해도 "Native module RNFBAppModule not found" 오류가 발생합니다.
Expo 푸시 토큰만 사용 가능: Expo Go에서는 Expo 푸시 토큰만 사용할 수 있습니다.
백엔드 호환성 문제: 백엔드가 FCM 토큰만 지원하는 경우, Expo Go에서는 푸시 알림 기능을 테스트하기 어렵습니다.
SDK 53부터 제한 강화: Expo에서는 SDK 53부터 Expo Go에서의 푸시 알림 기능이 제한된다고 안내하고 있습니다.
앱 개발 중에 푸시 알림과 관련하여 다음과 같은 문제가 발생할 수 있습니다:
이 오류는 Expo Go에서 Firebase 모듈을 사용하려고 할 때 발생합니다.
Expo Go는 사전 빌드된 앱이라 네이티브 모듈을 추가할 수 없기 때문입니다.
해결 방법:
1. 개발 단계에서는 Expo 푸시 토큰을 사용하도록 백엔드 개발자와 협의
2. 또는 개발 빌드(Development Build)를 생성하여 Firebase 통합
백엔드 API가 FCM 토큰 형식만 지원하는 경우, Expo 푸시 토큰으로 요청을 보내면 오류가 발생할 수 있습니다.
해결 방법:
1. 백엔드에 Expo 푸시 토큰도 지원하도록 요청
2. 임시 솔루션으로 Expo 푸시 토큰을 FCM 토큰처럼 전송하고, 백엔드에서 이를 구분하여 처리
3. 개발 빌드를 생성하여 실제 FCM 토큰 사용
푸시 알림 권한을 요청한 후 토큰이 제대로 저장되지 않아 알림이 표시되지 않는 문제가 발생할 수 있습니다.
해결 방법:
1. AsyncStorage에 토큰과 권한 상태를 명확하게 저장
2. 권한 요청 흐름이 제대로 구현되었는지 확인
3. 디버깅을 위해 콘솔 로그 추가
백엔드가 FCM 토큰만 지원하는 상황에서 Expo Go를 계속 사용하려면 다음과 같은 임시 해결책을 적용할 수 있습니다:
// Expo 푸시 토큰 가져오기
const expoPushToken = await Notifications.getExpoPushTokenAsync({
projectId: EXPO_PROJECT_ID,
});
// 백엔드에 토큰 전송 (임시로 Expo 토큰을 FCM 토큰처럼 전송)
try {
await axiosInstance.post("/device", {
fcmToken: expoPushToken.data, // Expo 토큰을 fcmToken으로 전송
deviceType: Platform.OS.toUpperCase(),
});
await AsyncStorage.setItem("notificationSettings", "true");
// 푸시 권한 상태 업데이트
} catch (error) {
console.error("Failed to register device:", error);
// 오류 처리
}
이 접근법을 사용하려면 백엔드 개발자와 협의가 필요합니다.
백엔드에서 Expo 푸시 토큰 형식을 인식하고 적절히 처리할 수 있도록 해야 합니다.
개발이 완료되고 앱을 실제 운영 환경에 배포할 때는 FCM을 사용하는 것이 권장됩니다.
이를 위해서는 다음과 같은 단계가 필요합니다:
Expo에서 FCM을 사용하려면 개발 빌드나 사용자 정의 빌드가 필요합니다:
# expo-dev-client 설치
npx expo install expo-dev-client
# 개발 빌드 생성
eas build --profile development --platform all
// FCM 설정
import messaging from '@react-native-firebase/messaging';
// FCM 권한 요청 및 토큰 가져오기
async function requestUserPermission() {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
const fcmToken = await messaging().getToken();
console.log('FCM Token:', fcmToken);
// 토큰을 백엔드에 전송
await sendTokenToBackend(fcmToken);
}
}
// 백엔드에 토큰 전송
async function sendTokenToBackend(token) {
try {
await axiosInstance.post('/device', {
fcmToken: token,
deviceType: Platform.OS.toUpperCase(),
});
await AsyncStorage.setItem('notificationSettings', 'true');
} catch (error) {
console.error('Failed to register device:', error);
}
}
// 포그라운드 알림 설정
messaging().onMessage(async remoteMessage => {
// 알림 표시 로직
});
// 백그라운드 알림 설정
messaging().setBackgroundMessageHandler(async remoteMessage => {
// 백그라운드 알림 처리
});
// 앱이 종료된 상태에서 열린 알림 처리
messaging().getInitialNotification().then(remoteMessage => {
if (remoteMessage) {
// 알림을 통해 앱이 열린 경우 처리
}
});
푸시 알림은 사용자 참여를 높이는 중요한 기능이지만, 구현 방식에 따라 복잡해질 수 있습니다.
Expo Go를 사용하는 개발 단계에서는 Expo 푸시 알림 서비스가 편리하지만, 백엔드가 FCM 토큰만 지원하는 경우 문제가 발생할 수 있습니다. 이런 상황에서는 백엔드 개발자와 협의하여 임시 솔루션을 마련하는 것이 좋습니다.
실제 운영 환경에서는 개발 빌드를 생성하여 FCM을 사용하는 것이 권장됩니다. 이렇게 하면 보다 안정적인 푸시 알림 기능을 제공할 수 있으며, Firebase의 다양한 기능도 활용할 수 있습니다.
푸시 알림 구현은 다소 복잡할 수 있지만, 사용자 경험을 크게 향상시킬 수 있는 중요한 기능입니다. 이 글이 FCM과 Expo 푸시 알림 서비스의 차이점을 이해하고, 개발 과정에서 발생할 수 있는 문제를 해결하는 데 도움이 되길 바랍니다.