한 사용자가 다수의 사용자에게 Push notification을 보내는 방법입니다. 이전에는 Firebase의 Cloud Messaging 콘솔에서 메시지 보내고 사용자 기기에서 수신하는 방법을 알아봤었습니다. 이번에는 콘솔을 이용하지 않고, 사용자 앱에서 보내는 것을 구현합니다.
총 3편으로 구성되어 있습니다.
1편: 개발환경 구축
2편: Push 토큰 저장 및 메시지 송신 코딩
3편: 메시지 수신 코딩 및 테스트
이번에는 3편 메시지 수신하는 코드와 테스트를 다뤄보겠습니다.
참고.
- https://rnfirebase.io/docs/v5.x.x/notifications/receiving-notifications
- React Native Firebase 푸시 알림(push notification), background listener - 2.firebase 리스너 구현
안드로이드폰 기준입니다. React Native로 구현하기 때문에, 1편에서 안드로이드 설정만 잘 되어 있다면 별도의 안드로이드 설정은 필요없습니다.
편의상 App.js파일에 구현합니다.
구현에 필요한 라이브러리를 추가합니다.
import firebase from 'react-native-firebase';
import { Alert, AsyncStorage } from 'react-native';
Alert의 경우는 앱이 켜져 있는 상태에서 메시지가 도착할 것을 알려주기 위해 추가했습니다. 별다른 용도는 없습니다. 앱이 켜져 있는 상태에서 메시지가 도착하면 Notification이 뜨지 않아서 메시지를 확인하지 않는 이상 메시지가 온지 알 수 없거든요.
1편에 잠시 설명드렸듯이 'react-native-firebaes'를 사용하면 별도의 초기화 작업이 필요없습니다. 그래서 아래와 같이 초기화 루틴을 주석처리 했습니다.
// create a component
class App extends Component {
async componentWillMount() {
/*
const firebaseConfig = {
apiKey: 'AIzaSyBmBbsfs4_AGBi6BITtytxytHXs8esnDNA',
authDomain: 'etainclub-73bd5.firebaseapp.com',
databaseURL: 'https://etainclub-73bd5.firebaseio.com',
projectId: 'etainclub-73bd5',
storageBucket: 'etainclub-73bd5.appspot.com',
messagingSenderId: '396912964585',
appId: '1:396912964585:web:9edea6b7c7a20bcd'
};
await firebase.initializeApp(firebaseConfig);
*/
}
메시지를 수신할 앱의 상태에 따라 메시지 수신 부분이 달라집니다. 앱의 상태는 다음 3가지 입니다.
- 사용자가 앱을 사용하고 있는 상태. foreground
- 앱이 백그라운드에서 도는 상태. background
- 사용자가 앱을 종료한 상태. close
위 세가지 경우에 대해서 수신 코드르 구현합니다. 여기서는 별도로 메시지 내용을 처리하지 않고, 단순히 console log만 합니다.
async listenerForNotifications() {
// app in foreground
this.notificationListener = firebase.notifications().onNotification((notification) => {
Alert.alert(notification.body);
console.log('onNotification', notification);
});
// app in background
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
console.log('onNotificationOpened', notificationOpen);
});
// app closed
const notificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
console.log('getInitialNotification', notificationOpen);
}
}
그러면 위에서 설정한 notification 인스턴스들을 아래와 같이 설정합니다.
async componentDidMount() {
this.checkPermission();
this.listenerForNotifications();
}
앱이 메시지 수신 가능한지 체크하고 권한을 얻기 위한 checkPermission 및 helper 함수들을 구현합니다.
async checkPermission() {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
this.getToken();
} else {
this.requestPermission();
}
}
async getToken() {
let fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
// user has a device token
await AsyncStorage.setItem('fcmToken', fcmToken);
}
}
}
async requestPermission() {
try {
await firebase.messaging().requestPermission();
// User has authorised
this.getToken();
} catch (error) {
// User has rejected permissions
console.log('permission rejected');
}
}
위 코드에서는 앱이 실행되면 push 토큰 정보를 얻어오고 마는데, push 토큰을 사용자 DB에 업데이트 해줘야 합니다. 그래야 push 토큰이 변경되더라도 메시지를 제대로 수신할 수 있게 됩니다. 이 부분은 나중에 테스트 후 구현하도록 하겠습니다.
마지막으로, 컴포넌트가 언마운트될 때 메시지를 수신할 수 있도록 아래와 같이 구현합니다.
componentWillUnmount() {
this.notificationListener();
this.notificationOpenedListener();
}
Foreground 상태에서 메시지 수신 테스트
두 개의 디바이스에 앱을 설치한 후에 테스트를 진행합니다. 디바이스1에서 메시지를 전송합니다.
이 때 메시지를 수신하는 device2는 앱이 켜진 상태로 foreground 상태로 둡니다.
메시지를 보내면 아래와 같이 앱이 켜진 상태로 alert창에 메시지와 함께 나타납니다.
![Screenshot_20190607-132406_etainclub.jpg]
()
Background 상태에서 메시지 수신 테스트
이번에는 device2를 앱을 종료하지 않고, 화면에서 내립니다. 즉 background에서 돌도록 합니다. 그런 후에 device1에서 메시지를 보내봅니다. 아래 그림과 같이 진동과 함게 Notification 바에 메시지가 도착합니다.
메시지를 누르면 앱이 foreground로 올라옵니다.
앱이 종료된 상태에서 메시지 수신 테스트
마지막으로, device2에서 앱을 확실히 종료시킨 후 device1에서 메시지를 보내봅니다. 아래 그림과 같이 앱이 종료된 상태에서도 Notification 바에 메시지가 나타납니다.
메시지를 누르면 앱이 실행되어 foreground 상태가 됩니다.
필요한 것?
메시지가 잘 수신됩니다. 다 된거 같습니다.
그런데, 정말 필요한 기능이 구현 안되었습니다. 그것은 바로 메시지가 오면 메시지 수신자들 화면에 도움 요청을 수락할지 말지 표시해주고, 수락이나 거절에 따른 처리를 해야 합니다.
지금까지 구현한 것으로는 Notification bar의 메시지를 눌러야 앱으로 연결이 됩니다. 메시지가 왔을 때 자동으로 앱의 특정 컴포넌트와 연결하기 위해서는 별도의 작업이 필요합니다.
아래 참고 글에서 4. background listener에 해당하는 내용입니다.
React Native Firebase 푸시 알림(push notification), background listener - 2.firebase 리스너 구현
복잡한 내용은 아니지만, 구현 방향을 정한 후 구현하도록 하겠습니다.
우선 지금까지 구현된 내용에 대단히 만족합니다. 중간에 작업하던 글이 사라져서 잠시 난감한적도 있지만 이타인클럽앱이 어느정도 구성을 갖춰 나가는게 보여서 기쁩니다.
함께 해요!
이타인클럽 - 우리 동네를 바꾸는 도움 선순환 운동
https://cafe.naver.com/etainclub