본 포스팅은 Android에서 Firebase FCM을 사용하는 두 번째 포스팅으로 서버 측 구현을 다루고 있습니다.
1. FCM Trigger 등록
이제 서버쪽 구현이 필요합니다. 여기서 서버는 Firebase – Clound Functions를 사용하여 구현할 예정입니다.
앞서 언급한데로 Firestore의 특정 document가 변경되면 document의 소유자에게 이를 알려주는 message를 보낼 것입니다.
이를 구현하기 위해 Firestore의 특정 document가 변경되는 것을 감지하여 동작하도록 trigger를 부착해야 합니다.
이는 생각보다 굉장히 쉽습니다.
아래 코드는 Firestore의 recruits에 {recruitId} document가 수정되면 동작하는 trigger입니다.
exports.myUpdateTrigger = functions.firestore
.document('recruits/{recruitId}')
.onUpdate(event => {
...
});
2. Send Message
위에서 등록한 Trigger에 실제로 message를 보내는 로직을 구현하는 것도 생각보다 간단합니다.
앞서 Firestore에 저장한 사용자 token 정보를 가져오고, 보내고자 하는 message를 담아 보내면 됩니다.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var db = admin.firestore();
exports.myUpdateTrigger = functions.firestore
.document('recruits/{recruitId}')
.onUpdate(event => {
...
// 1. Firestore에서 message를 받을 사용자에 해당하는 document 검색
var userRef = db.collection('users').doc(recruiterId);
var getUserDoc = userRef.get()
.then(doc => {
if (doc.exists) {
// 2. 사용자 document에서 이전에 저장해둔 fcmToken을 추출
const token = doc.data().fcmToken;
// 3. 사용자에게 보낼 Message 작성
const payload = {
data: {
title: "New Applicant!",
body: "There is a new applicant.",
recruitId: recruiterId
}
};
// 4. 사용자에게 Message 전송
admin.messaging().sendToDevice(token, payload);
} else {
console.log('notifyNewApplicant - No such document!');
}
})
.catch(err => {
console.log('[ERR] Error getting document', err);
});
});
앞서 1.2에서 Client가 수신한 message에서 특정 key를 통해 데이터를 추출해내는 부분이 있었습니다.
이때 사용하는 key는 바로 여기서 FCM이 생성한 Message 객체에 정의된 key와 일치합니다.
만약 추가로 다른 정보를 주고 받고 싶다면, payload의 data에 정의하여 사용하시면 됩니다.
구글에서는 위 시나리오에 대해 예제 코드를 제공하고 있습니다.
https://github.com/firebase/functions-samples/tree/master/fcm-notifications
[마무리]
간단한 코드 몇줄로 서버 없이 FCM을 구현할 수 있게 되었습니다.
직접 서버를 구축하여 구현한다고 생각했으면 아찔했을 텐데요.
Firebase 덕분에 굉장히 간단히 구현할 수 있었습니다.
처음에 Noti가 오는 걸 보고 감동받아 자리를 박차고 춤을 췄죠…
정말 신기합니다. 난 분명히 서버가 없는데 서버에서 message를 보내줍니다.
그리고 내 폰은 이걸 받아 Noti를 보여주죠!
Cloud Functions, Cloud Messaging을 통해 서버리스 서비스의 부족했던 2%가 개운하게 메꿔지는 기분입니다.
다만 한가지 더 추가로 알아보고 싶은 점이 있습니다.
성능 관련한 부분인데요. Firestore의 데이터가 변경되고 trigger에 의해 메세지를 보내고, 이를 받아 Noti를 보여주기 까지 시간이 은근히 걸린다는 것입니다.
이상적으로는 사용자가 버튼을 누르자마자 1초 이내에 다른 쪽 디바이스에서 띠링하고 Noti가 오길 기대했는데, 1초는 커녕 수초가 걸립니다.
의심가는 부분은 제가 구현하여 테스트한 프로젝트가 하필이면 Region을 미국으로 선택하여 만든 탓에 그런건지…
아니면 대한민국으로 지정했어도 그랬는지…
'개발 > Android' 카테고리의 다른 글
BroadcastReceiver에서 Background thread를 사용 시 주의 사항 (0) | 2020.11.08 |
---|---|
[Android] 앱 출시 전 체크 사항 14가지 (번역) (0) | 2020.11.08 |
[Android] Firebase FCM을 사용하여 서버 없이 push 알림 구현하기 – part 1 (0) | 2020.11.08 |
[Android] SharedPreference commit과 apply (0) | 2020.11.08 |
[Android] 화면 방향 변경 시에도 RecyclerView의 Position 유지하기 (0) | 2020.11.08 |