Firebase Cloud Messaging

quokka·2022년 6월 12일
0

.

목록 보기
5/5

Firebase Cloud Messaging

푸시 알림을 간편하고 안정적으로 보내기 위해서 Firebase Cloud Messaging을 사용한다.

FCM(Firebase Cloud Messaging)은 무료로 메시지를 안정적으로 전송할 수 있는 교차 플랫폼 메시징 솔루션이다.

FCM을 사용하지 않고, 안드로이드 Service를 사용해 소켓 연결을 항상 유지하거나 polling 방식을 사용할 수도 있지만 배터리 성능이나 doze mode에서의 푸시 알림 처리, 교차 플랫폼 메시징 등을 고려했을 때 FCM을 사용하는 것이 합리적이다.

FCM 아키텍처

https://firebase.google.com/docs/cloud-messaging/fcm-architecture?hl=ko

FCM을 통해 푸시 알림을 보내는 과정은 아래 사진처럼 진행된다. 간단히 설명하면 푸시 서버에서 FCM backend로 알림 내용과 타겟이 되는 디바이스의 토큰을 담아 Post 요청을 보내면 FCM이 클라이언트로 알림을 보내는 것이다.

  1. 모든 메시지 유형을 자동화하고 지원하려면 Firebase Admin SDK 또는 FCM 서버 프로토콜을 지원하는 신뢰할 수 있는 서버 환경에서 메시지 요청을 구현해야 한다.
  2. FCM 백엔드는 메시지 요청을 받고, 메시지 ID와 같은 메시지의 메타데이터를 생성한다.
  3. Platform-level message transport에서는 메시지를 타겟 디바이스로 라우트하고, 메시지 전송을 처리한다. 플랫폼 별 전송 레이어로 메시지를 보낸다. 안드로이드는 ATL을 통해, 애플 기기는 APNs를 통해, web app은 web push protocol을 통해 전송된다.
  4. 유저 기기의 SDK에서는 알림이 표시되거나, application 로직에 따라 메시지가 처리된다.

토큰 등록 과정

  1. 모바일에 앱이 설치되는 순간 Firebase 서버에 키 획득을 위한 요청을 보냄
  2. Firebase 서버에서 키를 만들어 모바일에 전달
  3. 모바일 앱에 전달된 키를 서버에 전송
  4. 서버는 전달받은 키를 db에 저장하여 타겟 모바일의 identification으로 사용
  1. 서버에서 데이터를 타겟 모바일에 전달하기 위해 DB에서 키를 획득
  2. DB의 키와 전송하고자 하는 데이터를 HTTP 통신으로 Firebase 서버에 전달
  3. Firebase 서버에서는 전달받은 키값을 식별해 타겟이 될 클라이언트 기기 식별
  4. 타겟 푸시 알림 (타겟 모바일의 앱은 백그라운드에 있는 상태에서도 리스너로 이벤트를 감지함)

FCM 등록 토큰 관리

오래된 등록 토큰이 있는 비활성 장치에 메시지를 전송하여 리소스를 낭비하고 있을 수 있다. FCM 등록 토큰은 서버에서 저장하여 관리하는데, 클라이언트의 토큰과 active 토큰을 추적하면서 관리한다. 이를 관리하는데는 token timestamp 사용을 권장한다.

  • 신선하지 않은 토큰은 삭제한다. 유효하지 않은 토큰을 제거하는 것 뿐만 아니라 토큰이 신선하지 않다는 것을 모니터링할 필요가 있다.
  • 앱이 처음 시작할 때 FCM SDK는 클라이언트 앱 인스턴스에 대한 등록 토큰을 생성한다. 앱 초기 시작 시 토큰을 타임스탬프와 함께 앱 서버에 저장한다.
  • 아래 경우 토큰이 변경되므로 업데이트해야 한다.
    • 앱이 새 기기에서 복원되었다.
    • 사용자가 앱을 제거/재설치한다.
    • 사용자가 앱 데이터를 지운다.
  • 서버의 모든 등록 토큰은 주기적으로 검색하고 업데이트하는 것이 좋다. 토큰 변경 여부와 관계없이 정기적으로 토큰의 타임스탬프를 업데이트하는 서버 로직을 추가한다. (한 달에 한 번 업데이트 하는 것을 권장)

메시지 유형

https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko

FCM 메시지에는 notification과 data가 있다.

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    }
		"data":{
      "Nick" : "Mario",
      "body" : "great match!",
      "Room" : "PortugalVSDenmark"
    }
  }
}

notification 메시지

클라이언트 앱이 아닌 FCM이 자동으로 사용자 기기에 알림을 표시한다.

notification이 있으면 백그라운드 상태에서 onMessageReceived()가 호출되지 않고 default 세팅으로 알림이 간다.

notification 내용이 없으면 백그라운드 상태에도 onMessageReceived()가 호출되어 data에 담겨있는 값을 사용해 커스텀 알림을 보낼 수 있다.

data 메시지

클라이언트 앱이 메시지를 처리한다.

백그라운드 상태

  • 백그라운드 상태인 경우 notification 항목이 있을 때 notification에 작성된 내용으로 알림이 수신되고, 사용자가 알림을 탭한 경우에만 앱이 데이터 페이로드를 처리한다.
  • 백그라운드 상태에서 POST 요청에 notification이 포함되어 있다면 FCM sdk는 알림이 왔을 때 notification의 title, body 값을 가져와 default 세팅대로 클라이언트 알림을 띄운다.
  • notification 값이 없으면 onMessageReceived()가 호출되어 클라이언트 앱 코드에 따라 커스텀된 알림을 띄울 수 있다.

포그라운드 상태

  • 포그라운드 상태에서는 앱에서 notification과 data가 모두 포함된 message 객체를 수신한다. 포그라운드 상태에서는 data에 작성된 내용으로 알림이 뜬다.

플랫폼 공통 필드

  • message.notification.title, message.notification.body, message.data는 플랫폼 관계없이 공통으로 사용된다. 특정 플랫폼에만 값을 보내려면 공통 필드가 아닌 플랫폼별 필드를 사용한다.

메시지 구문

다운스트림 메시지 구문 이 링크에서 HTTP JSON 메시지의 대상, 옵션 및 페이로드를 확인할 수 있다.

REST Resource: projects.messages 이 링크에서 메시지 형식과 옵션을 확인할 수 있다.

FCM 서버 옵션

  • Firebase Admin SDK ( 서버에 Firebase Admin SDK 추가 )
  • FCM HTTP v1 API 가장 최신 프로토콜로서 보다 안전한 승인과 유연한 크로스 플랫폼 메시징 기능을 제공한다.
  • 기존 HTTP
  • XMPP 클라이언트 애플리케이션에서 업스트림 메시징을 사용하려면 XMPP를 사용해야 한다. (HTTP는 다운스트림 전용)

장애 상황

FCM을 통해 푸시 알림을 보내면 서버와 클라이언트 앱과의 연결은 불필요하다. 하지만 클라이언트 앱이 오프라인 상태가 되는 등 FCM으로부터 메시지를 받을 수 없는 상황이 발생할 수 있다. FCM이 서버로부터 Post 요청을 받았다면 FCM은 기본적으로 클라이언트 앱이 메시지를 받을 때까지 계속 전송을 시도한다.

메시지 수명

https://firebase.googleblog.com/2019/02/life-of-a-message.html

https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko#lifetime

https://firebase.blog/posts/2019/02/life-of-a-message

서버에서 FCM으로 푸시 요청을 보내면 FCM 백엔드에서 요청을 성공적으로 받았다는 success 응답을 준다. 하지만 이 응답이 클라이언트 앱 푸시를 성공했다는 의미는 아니다.

FCM이 요청을 받으면 아래 상황에 도달할 때까지 계속 클라이언트 앱으로 푸시 알림을 시도한다.

  1. The message expires

    정해진 메시지 수명이 끝나면 푸시 알림을 더 이상 보낼 수 없다. 디폴트 메시지 수명은 28일이다. 최대 28일동안 FCM은 전송 실패한 메시지를 보관하고 전송이 가능할 때까지 계속 시도한다.

  2. 다른 메시지로 인해 사라짐

    collapse key를 설정했다면 기존 메시지가 새로운 메시지로 대체된다. collapse key를 별도로 설정하지 않았다면 FCM은 보내지 못한 메시지를 모두 보관한다.

  3. 디바이스가 한 달 이상 오프라인 상태인 경우

    FCM는 디바이스가 온라인 상태인지, 언제부터 오프라인 상태였는지에 대한 정보를 가지고 있다. 한 달 이상 오프라인 상태였다가 온라인으로 돌아가면 FCM은 보관 중이던 메시지가 삭제 되었다는 것을 디바이스에게 알려준다.

  4. 대기 중인 메시지가 100개 초과

Android / iOS / Web 각 경우에 발생할 수 있는 delivery factors

https://firebase.blog/posts/2019/02/life-of-a-message#android-message-delivery-factors

안드로이드의 경우

  1. Doze mode

    기기의 화면이 꺼진 상태로 오래두면 안드로이드는 배터리 소모를 줄이기 위해 Doze mode가 활성화된다. 이 때 FCM은 중요도가 normal인 메시지는 보내지 않고 기기의 doze mode가 끝날 때까지 대기한다. 중요도가 high인 메시지는 전송된다.

  2. Background Restrictions

    안드로이드는 사용자가 강제로 앱의 백그라운드 실행을 제한할 수 있다. 이 경우 FCM이 푸시 알림을 전송하지 못할 수 있다.

  3. 전력 관리 제한

    https://developer.android.com/topic/performance/power/power-details

    App standby buckets에 따라 FCM의 푸시 알림의 중요도가 high여도 메시지가 전송되지 않을 수 있다. 예를 들어 기기가 절전 모드이고 앱이 빈도가 낮은 버킷에 있다면 메시지 전송이 연기될 수 있다.

  4. Uninstalled application

    FCM이 메시지 전송을 시도하는 중에 앱이 삭제되면 메시지는 즉시 폐기된다.

단일 기기에 대한 최대 메시지 속도

단일 기기에 전송할 수 있는 최대 메시지 수는 분당 240개, 시간당 5,000개다. 이 한도는 전송 로직 오류로 인해 의도치 않게 기기의 배터리가 방전되는 것을 방지한다.

0개의 댓글