FCM 모바일 푸쉬 성능 개선
2021년 4월 5일 초안 작성
실험 환경
이름 | topics | FCM Token |
---|---|---|
LG Q9 | all | fwfpbo4mTzyP4SgAYn…ATlSMJNcF |
블랙베리 KEY2 | all, grandeur | eofvKj0fQBWOMf4n8Y…TykGzDnPQ |
갤럭시 노트 9 | all, grandeur, sonata | cBKI6DLiS52ekPM43g…2HiQT0014 |
갤럭시 S9 | all, sonata | f-LXcs68Qv2jVGy955…j2uzasWqq |
내용
- 카카오톡은 수백만명도 즉시 실시간 푸쉬를 보내는데, 그렇게 할 수 없을까.
- 비용을 들여서 유료 솔루션을 도입하면 해결되는 문제일까.
- 왜 사용자 목록을 매 번 서버가 전달해야 하는지. 미리 등록해두었다가 필요할때 즉시 발송 명령을 내릴 수 없을까.
- 메시지는 pub/sub 모델이 없을까.
접근 방법
- Firebase는 기기의 Token을 알고 있다. 그렇다면 Firebase가 미리 타겟을 분류하고 있다면 이를 이용해 즉시 메시지를 보낼 수 있지 않을지
- Firebase Cloud Messaging(이하 FCM)이 어떤 방식으로 메시지를 보내는지 확인 필요
- 안드로이드 샘플 앱을 만들어 푸쉬 방식을 실험해본다.
- 예전에 Topic으로 분류하면 즉시 보낼 수 있다고 알려준 바 있음. 이 방식이 타겟팅 아닌가. 활용할 수 있을지 실험 필요
발송 방법
- 발송은 REST로 한다.
- 분류도 서버에서 한다. 발송은, 테스트는 REST로 구현하지만 실서비스에는 Admin SDK를 활용하여 Java 기반으로 구현한다.
- 서버 어드민에서 정교하게 타겟팅 하는 기능을 제공하고 여기서 curl 등으로 해당 Topic으로 보내면1 될 것 같다.
- Topic은 Boolean Operators를 지원하기 때문에 적절하게 타겟팅만 할 수 있다면 충분히 정교하게 보낼 수 있을 것 같다.
발송 결과
실험해보니 발송이 잘 된다.
한 대를 지정해서 발송하면 다음과 같다.
Topic을 이용한 단체 발송 화면은 다음과 같다.
장점
- 전체 발송 결과 및 리텐션 여부를 확인할 수 있다.
- 시간차가 있긴 하나 발송하려는 Topic에 대상자가 얼마나 되는지 미리 확인도 가능하다.
채널
안드로이드 최신 버전에는 Notification Channel이 존재하여 채널 별로 메시지의 중요도와 Sound 발생 여부를 설정할 수 있다. (앱 내에서는 카테고리로 표현됨)
그러나 해당 채널을 구독하지 않고 있더라도 아무 채널이나 보내면 메시지가 발송되기 때문에 사실상 메시지 발송을 제한하는 용도로는 쓸 수 없다.
오류
물리기기가 아닌 경우 다음 오류로 실행되지 않았다.
E/FirebaseInstanceId: Failed to get FIS auth token
java.util.concurrent.ExecutionException: com.google.firebase.installations.FirebaseInstallationsException: Firebase Installations Service is unavailable. Please try again later.
Android Emulator는 지난 주에는 됐는데 이번 주 부터 동일한 오류가 발생한다. BlueStacks도 당연히 안되고, 지금까지는 물리 기기에서만 동작한다. QA에 요청하여 기기 3대를 임대하여 내 기기 1대와 함께 4대를 테스트 기기로 활용한다. iOS도 추가할까 했으나 실험의 편의를 위해 일단 안드로이드로 제한한다.
API
Server Key를 사용하는 기존 방식은 DEPRECATED 되었다. 신규 API를 활용하도록 한다. 기존 방식 전환 가이드2에 따라 OAuth2가 필요하다. OAuth2는 Google Developers OAuth 2.0 Playground3를 활용하면 쉽게 토큰을 발급 받을 수 있다.
제약 사항
- 기존 처럼 사후 타겟팅 발송은 더 이상 지원하지 않으며 사전에 타겟팅 하여 Topic에 추가한 상태여야 한다.
- 신규 등록된 Topic은 Firebase에 등록되는데 하루 정도 지연이 있다.
- 반드시 FCM에서 메시지를 발송해야 하며 하나의 Topic에 대해서만 메시지 발송이 가능하다.
- 두 개 이상의 Topic에 대해서도 Boolean Operations(AND, OR)로 설정이 가능하다. 단, 이 경우 서버에서만 발송할 수 있으며 발송 이후 추적이나 관리는 지원되지 않는다.
- FCM에서 메시지 발송 여부가 표시되지만 시간 지연이 있다.
- FCM이 완전히 실시간으로 발송되지는 않는다. 최대 1분 정도 지연이 확인되었다.
가이드
앱 개발
Firebase Cloud Messaging을 연동한다.
- 안드로이드: https://firebase.google.com/docs/cloud-messaging/android/client
- iOS: https://firebase.google.com/docs/cloud-messaging/ios/client
서버 요청시 FCM Token 정보도 항상 함께 내려준다. (헤더에 포함)
백엔드
- 회원 가입 또는 정보 변경시 적절한 Topic을 subscribe/unsubscribe 해주는 기능이 필요하다.
- 메시지 수신 거부시 기존 Topic을 백업하고, 모든 Topic을 unsubscribe 하는 기능이 필요하다. 나중에 다시 메시지 수신시 백업한 Topic을 re-subscribe 한다.
기타
- FCM 가이드를 보면 이미지도 알림창에 띄워줄 수 있다고 나온다.
- Eclipse Mosquitto™를 사용하여 pub/sub을 직접 구현하는 방식인데, 이 경우 정말로 푸쉬 서버를 구현해야 하는 이슈가 있다. 구현하려는 서비스가 채팅 서비스도 아닌데 직접 pub/sub 까지 구현하는건 지나친 오버 엔지니어링이다.