이전 포스팅에서 FCM에서 보낸 메시지를 React Native 앱에서 받는 방법에 대해서 다뤘다. 이번 포스팅에서는 FCM 에서 메시지를 보내는 것을 해볼 것이다.
파이어베이스 콘솔에서 보낼 때는 GUI로 구성되어 있기 때문에 매우 간단하고 쉽다.
파이어베이스 콘솔 가기
보낼 알림의 제목과 내용을 입력한다.
알림을 보낼 타깃을 정한다.
알림을 보낼 시간을 정한다.
사용자에게 알림을 보내고 수신이 확인되면, 파이어베이스 애널리틱스의 특정 이벤트를 걸어서 측정할 수 있다.
이렇게 설정을 마친 후 검토를 누르고 전송하면 끝이다!
FCM 서버에서 앱으로 알림이 전송되기까지 조금의 시간차가 존재하는 것으로 보인다.
안드로이드 에뮬레이터로 알림이 전송된 모습
안드로이드 에뮬레이터는 알림이 제대로 전송이 됐지만, iOS는 아무리 기다려도 알림이 전송되지 않았다.
일단, 이전 세팅에서도 다뤘지만 iOS는 시뮬레이터에서는 알림을 받을 수 없다.
FCM에서 보내는 알림이 애플의 APNs를 거쳐서 보내지는데 이때 물리적인 디바이스외에는 푸쉬알림이 가지 않는다.
여기서 분명 물리적 디바이스를 연결하여(이거 하려고 당근에서 아이폰 하나 25만원 주고 사왔다..) 했는데도 되지 않아서 구글링을 해봤고
해결책 링크 다음 링크에서 문제점을 찾을 수 있었다.
[FCM: 2편]파이어베이스 추가 세팅하기 편에서 iOS 추가 세팅을 할 때, 생성했던 Identifier에 푸시알림과 관련한 Certificates을 등록해주어야 한다.
공식문서에는 빠져있었던거 같다..
위와 같이 체크된 Push Notifications에 Edit 버튼을 눌러 production과 distribution 버전의 Certificate을 생성해서 추가해야 한다.
다음과 같이 CertificateSigningRequest.certSigningReques
파일을 통해 Certificate을 만들어주고 key 파을 모두 저장한다.
(이 Certificate, Identifier, Profile 등은 매번 헷갈려서 한번 제대로 정리를 해야겠다..)
이렇게 Certificates 2개를 추가적으로 생성해주면, FCM에서 보낸 메시지를 iOS 물리적 디바이스에서도 받는 것을 확인할 수 있다!
공식문서만 보고 차근차근 따라가면서 개념들을 익혔는데 뿌듯하면서 긴 여정이었다..!!
(공식문서가 이렇게 중요하다는 것을 새삼 느낀다.)
끝난줄 알았지만 흥미로운게 하나 더 있었다..!!
유저가 푸시알림을 눌렀을 때, 앱이 무조건 열리게 되는데 이는 FCM 메시지는 앱이 백그라운드에 있을 때만 보내기 때문이다.
푸시알림이 눌렸을 때를 감지해서 다른 결과를 보여줄 수 있을 것이다.
(푸시알림을 눌렀을 때 앱이 열리면서 바로 특정 페이지로 넘어가는 경우가 이것으로 구현 가능하다.)
이를 위해서는 두가지 메소드가 쓰이는데,
getInitialNotification
: 앱이 Quit 상태에서 열렸을 때onNotificationOpenedApp
: 앱이 Background 상태에서 열렸을 때이들을 활용해서 푸시알림에 따라 React Navigation의 화면 이동을 실행하는 로직을 짜보도록 하자.
import React, { useState, useEffect } from 'react';
import messaging from '@react-native-firebase/messaging';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function App() {
const navigation = useNavigation();
const [loading, setLoading] = useState(true);
//여기서 초기 Route를 동적으로 설정하는 재밌는 발상이 등장한다.
//앱이 Quit 상태에서 열릴 때는 이 초기 Route를 변경해준다.
const [initialRoute, setInitialRoute] = useState('Home');
useEffect(() => {
//FCM 메시지의 data payload에 type이라고 하는 특성이 담겨져서 보낸다고 가정해보자.
//이 "type" 특성은 푸시알림을 눌렀을 때, 이동할 페이지에 대한 정보를 나타낸다.
//앱이 Background에서 열릴 때는 navigate 메소드를 이용해서 다른 remoteMessage.data.type의 화면으로 이동한다.
messaging().onNotificationOpenedApp(remoteMessage => {
console.log(
'Notification caused app to open from background state:',
remoteMessage.notification,
);
navigation.navigate(remoteMessage.data.type);
});
//앱이 Quit 상태에서 열릴 때, getInitialNotification 메소드를 사용하고
//setInitialRoute로 초기 Route를 설정한다.
messaging()
.getInitialNotification()
.then(remoteMessage => {
if (remoteMessage) {
console.log(
'Notification caused app to open from quit state:',
remoteMessage.notification,
);
setInitialRoute(remoteMessage.data.type); // e.g. "Settings"
}
setLoading(false);
});
}, []);
if (loading) {
return null;
}
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={initialRoute}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
이렇게 FCM을 React Native에 적용해보는 튜토리얼을 보고 마치게 되었다.
추가적으로 firebase.json
을 다루고 싶지만, 시간이 되면 다뤄볼 것이다.