평범한 개발자 행복한 가족, 패밀리그램

개발/안드로이드

FirebaseMessaging 적용, App Background 상태 이슈

패밀리그램 2017. 1. 9. 22:14



기존에 GCM을 Firebase로 마이그레이션 하면서 포스팅 해야지 계속 미루다 이제서야 포스팅한다.

Firebase에서 CloudMessage 기능이 추가 되었다. 기존에 Push 서버 없이도 Push를 보낼 수 있을 수 있게 된 것이다.


아래 내용을 확인하기 전에 참고하기 전에 알아할 점은 FirebaseMessaging은 Client App에서 Push서비스를 구현만 하면 Notification은 Firebase 관련 SDK에서 노출시켜 준다는 것이다.

그리고 기존에 GCM Json과 크게 변함이 없는 구조로 데이터가 Service로 수신된다는 것 이다.


Google Document FCM Migration


기존 GCM에서 Migration 은 Google 가이드만 따라해도 충분히 할 수 있다.



1. 기존 GCM 과 FirebaseMessaging의 Payload


기존 GCM을 curl 또는 REST API 툴로 전달 할 때 payload로 아래의 형식의 데이터를 전달 하였었다.


{
   
"collapse_key" : "demo",
   
"delay_while_idle" : true,
   
"to" : "xyz",
   
"data" : {
     
"key1" : "value1",
     
"key2" : "value2",
   
},
   
"time_to_live" : 3
 
},

기존 GCM 에서 to 안에는 client gcm key가 들어가게 되어있었다.

Firebase Console을 통해 메세지를 전달하면 기존과 다르게 notification 블럭이 추가되어 전달 된다.

{
 
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
 
"priority" : "normal",
 
"notification" : {
   
"body" : "This week’s edition is now available.",
   
"title" : "NewsMagazine.com",
   
"icon" : "new",
 
},
 
"data" : {
   
"volume" : "3.21.15",
   
"contents" : "http://www.news-magazine.com/world-week/21659772"
 
}
}

FirebaseMessaging의 to 에는 client gcm key 또는 topic이 들어 갈 수 있다.


개인적으로 개발하면서 확인한 부분은 notification 블럭은 Client에 구현한 FirebaseMessagingService로 전달되는 것이아니라 Firebase SDK 내에서 처리하는 내용이었다는 것이다.


만약 App에 foreground상태라고 한다면 SDK에서 먼저 notification 블럭에 맞게 Notifiaction을 노출시킨다. 그 후 App 에 구현된 FirebaseMessagingService로 data 블럭이 전달된다.



아마도 위 이미지에 "메세지 내용" 입력 창이 notification 블럭으로 전달 되는 듯 하다.


그리고 아래 고급옵션을 추가로 입력하게되면 key, value 가 data 영역으로 전달되는 것을 추측 할 수 있다.



2. App Backgound 상태에서 구현된 FirebaseMessagingService로 Push Message 받기


그런데 만약 App이 Killed 된 상태이거나 background 상태라면 Firebase SDK 로만 notification 블럭이 전달되고 data 블럭은 App으로 전달 되지 않는다.

그렇기 때문에 벌거숭이 같은 기본 Notification이 노출된다.

(이게 뭔 거지 같은 상황인가. 기존 GCM을 많이 구현해봤다면 익숙하지 않는 형태이다)


FirebaseSDK가 title, message 만 간단하게 노출시키고 notification 블럭에 target Activity 가 지정되어 있다면 해당 Activity의 Intent로 data 영역이 전달 된다.

위와 같은 방법으로 전달하는 방법은 아래와 같다.


curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  -d "{\"to\":\"/topics/news\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"OPEN_ACTIVITY_1\"}}"
<intent-filter>
  <action android:name="OPEN_ACTIVITY_1" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

출처 : http://stackoverflow.com/questions/37407366/firebase-fcm-notifications-click-action-payload


payload는 아래와 같다.

{
 
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
 
"priority" : "normal",
 
"notification" : {
   
"body" : "This week’s edition is now available.",
   
"title" : "NewsMagazine.com",
   
"icon" : "new",

"click_action" : "OPEN_ACTIVITY_1"
 
},
 
"data" : {
   
"volume" : "3.21.15",
   
"contents" : "http://www.news-magazine.com/world-week/21659772"
 
}
}

위와 같이 전송하면 Notification 클릭 시 click_action에 명시된 Activity가 열리고, data 블럭은 intent에 실려 들어온다.

만약 Push Service가 많은 기능을 하지 않는다면 위와같은 방법을 사용하는 것도 개발시간을 단축 시키는 현명한 방법이다. 단, Notification Style을 지정한던가

Network 이미지를 원하는데로 구현하기엔 한계가 있다. 


그렇기 때문에 이전과 같은 방법으로 구현된 PushService에서 처리하고 싶다면 Firebase Console에서 전송하면 안된다. (ㅠㅠㅠㅠㅠㅠ)

간단하게 Push전송 시스템을 구축 하던가, Restful API 툴을 사용하던가, curl을 사용해야 한다.

(개인 개발자라면 그냥 RESTFUL API 툴을 사용하자. 그게 편하다 ㅋㅋ)


notification 블럭을 제외하고 전달한다면 바로 구현된 PushService로 data 블럭이 전달되는 걸 확인 할 수 있다.


FirebaseMessaging은 분명 클라이언트 개발자에게 간단한 Message전달을 빠르게 개발 할 수 있게 도와주는 건 분명하다.

하지만 기존 커머스 앱은 Notification 커스텀이 많기 때문에 적합하지 않는 것도 사실이다.

(이 부분은 분명 다른 방법이 있을 수 도 있지만, 내가 내린 결론은 이것이다.)


개인적으로 개발하는 앱들은 간단한 Firebase Messaging 을 사용해 볼 예정이다.

반응형