해당 글에서는 FCM 서버로 메시지를 전송하는 protocol에 대해서만 살펴볼 것이며,
SDK를 이용한 클라이언트 작업은 https://firebase.google.com/docs/cloud-messaging 에서 자세히 확인할 수 있다.
FCM Provider 에 대한 예제는 https://github.com/chulman/firebase-cloud-messaging 에 작성하였다.
Protocol
- 기본적으로 HTTP와 xmpp를 통해 메시지를 전송할 수 있다.
|
HTTP |
XMPP |
UpStream/DownStream |
다운스트림 전용 최대 4kb의 데이터 |
업스트림/다운스트림 최대 4kb의 데이터 |
메시징 방식 |
Request & Response -> 응답받기 전까지 다른 메시지를 보내지 못하도록 차단. |
승인 또는 실패(ACK or NACK Json 인코딩 XMPP 메시지 형태)를 비동기적으로 보냄 |
JSON |
HTTP POST로 전송된 JSon message |
JSON MESSAGE가 XMPP 메시지로 캡슐화 됨. |
일반텍스트 |
HTTP POST로 전송된 일반 텍스트 메시지 |
지원하지 않음. |
멀티캐스트 다운스트림이 여러 등록 토큰으로 전송 |
JSON Message 형식에서 지원 |
지원하지 않음. |
HTTP API
- Http API로 메시지를 전송하는 포맷은 http api 와 http v1 api 2가지가 존재한다.
- http v1 api를 사용하려면 google api 대쉬보드를 통해 등록해야 한다. (참조: Google API 대쉬보드에 FCM API 설정하기)
1. http api VS http v1 api
- http api는 가장 심플한 레거시 방식으로 오랫동안 많은 사람들이 써왔던 방식이다. 특정 url로 규격에 맞는 json 포맷을 통해 전송하기 만하면 된다.
- http v1 api는 http api를 보안한 api라고 생각하면 될 것 같다. 가장 크게 강조하는 2가지는 보안과 멀티 플랫폼이다.
+ (1) 보안 : http v1 api 는 oauth 방식을 통해 fcm 서버와 연결하고 인증한다. (때문에 좀 더 까다롭다..)
+ (2) 멀티 플랫폼 : 기존 http api를 통해 메시지를 전송할 때는 보내는 형식이 기기 중심적이었다. 여러 기기를 묶어서 공통된 메시지를 보낼 수 밖에 없었는데, 이를 보완하고 플랫폼 별(ios, android..) 다양한 메시지 내용과 포맷을 하나의 json 포맷으로 구성할 수 있고 때문에 한 번의 전송으로 여러 플랫폼에 메시지 전송이 가능하다.
(해당 fcm 블로그에서 자세한 사항을 확인할 수 있다.) - https://firebase.googleblog.com/2017/11/whats-new-with-fcm-customizing-messages.html
2. request header
- request option : 메시지를 전송 할 때는 POST 방식이어야 한다.
- url :
+ http api : https://fcm.googleapis.com/fcm/send
+ http v1 api: https://fcm.googleapis.com/v1/{parent=projects/*}/messages:send
- port : 주의할 점은 htps를 통한 연결이 때문에 443 포트에 대한 방화벽 정책이 허용되어야 한다.
- content type : application / json
- parameter :
+ http api : "authrization" : key = "api 서버 키"
+ http v1 api: "authrization" : bearer + "api 서버 키"
3. request body
- 메시지를 전송할 때 body에 json 형식의 payload를 보낼 수 있는데 format은 아래에서 확인할 수 있다.
+ https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko
3.1 http api 요청 포맷 예
아래 포맷을 보면 특정 토큰(기기)에 notification이라는 메시지 형식을 통해 알림 형태를 지정하며, 커스텀 데이터를 추가해서 사용자가 메시지를 좀 더 다양하게 파악 할 수 있다.
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
}
- 여러 토큰에 타겟해서 보낼 경우 registration_ids를 설정해서 보낼 수 있는데, 배열 갯수의 제한은 1000개 이다. 즉 한 번 전송시 1000개까지 밖에 전송할 수 없다.
{
"message":{
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
},
"registration_ids": ["bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", ...]
}
}
- 때문에 FCM에서는 TOPIC이라는 키를 활용해서 좀 더 많은 디바이스에 한번에 전송할 수 있는 방법을 제공한다. 다음과 같이 메시지를 전송하면 "NEWS"라는 토픽을 등록한 기기에 모두 전송한다.
{
"message":{
"topic" : "NEWS",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
}
3.2 http v1 api 요청 포맷 예
- 여러 플랫폼에 전송할 수 있는 형식을 사용할 수 있다.
{
"message":{
"topic":"subscriber-updates",
"notification":{
"body" : "This week's edition is now available.",
"title" : "NewsMagazine.com",
},
"data" : {
"volume" : "3.21.15",
"contents" : "http://www.news-magazine.com/world-week/21659772"
},
"android":{
"priority":"normal"
},
"apns":{
"headers":{
"apns-priority":"5"
}
},
"webpush": {
"headers": {
"Urgency": "high"
}
}
}
}
4. response header & Error Code
- 참조: https://firebase.google.com/docs/cloud-messaging/http-server-ref?hl=ko#error-codes
5. response body
- 마찬가지로 http api와 http v1 api의 response body는 다르다.
5.1 response body
- 전송 시 registration_ids 키값 에 5개의 기기를 포함했을 때, body 다음과 같은 형식이 될 것이고 5기기의 결과 값이 result 배열에 포함된다.
- http v1 api로 전송시 성공한다면 다음과 같은 형식으로 응답을 내 뱉는다.
{"name": "projects/{project-name}/messages/2280331808525169080"}
- 가장 큰 문제점은 에러가 발생했을 때 처리 부분인데, 에러코드가 너무 빈약하다는 점이다. 자세하게 확인하려면 admin sdk를 통해 따로 요청하는 등 방법이 존재하는데 이에 따른 비용이 더 생길 우려가 있다.
'Cloud & NoSQL & Middleware > Firebase' 카테고리의 다른 글
Google API 대쉬보드에 FCM API 설정하기 (0) | 2020.03.21 |
---|---|
FCM(Firebase Cloud Messaging) (2) - Architecture (0) | 2020.03.21 |
FCM(Firebase Cloud Messaging) (1) - 개념 (1) | 2020.03.21 |