로딩...

fcm

firebase cloud message

overview

사용패턴

  • notification
  • data sync
    • 활용패턴이 있을 것 같음 특정 ui 버전을 보게 한다던가, de-feature 해버린다던가
  • updating ui

사용

client

  • 중요 백그라운드 메시지 처리에 제약사항으로 인해 코드가 로딩되는 이른 시점에 firebase 설정이 되어야한다
  • ios 는 백그라운드에서 메시지를 받았을때 리액트 루트가 마운트되며 이로인한 문제를 방지하기 위한 설정이 필요하다

firebase.json

추가 설정을 위해서 자동으로 해주는 것들을 disabled 시키는 등, 특정 설정 가능

  • ios
    • disable APNs auto registration
    • foreground presentation options - notification 보여지는 방식
  • android
    • background handler timeout 설정, background, quit 상태에서 메시지를 핸들링할 타입지정 -> 지나면 앱 quit으로 추정
    • Notification Channel ID
    • Notification Color
  • Auto initialization

app 의 상태따른 행동

메시지 타입

data only 메시지는 low priority 로 간주되며 앱을 깨우지 않는다, 우선순위를 강제하면 깨울 수 있다

  • data + notification
  • data

server

  • 메시지를 보내는 방식
    • 메시지를 특정 디바이스에 보내는 방식
    • 메시지를 토픽에 발송하는 방식
      • 토픽을 구독하는 주체는 앱
      • 서버가 토픽에 메시지를 발송(한번에 최대 5개 토픽)
      • 주의 특정 유저를 위한 토픽을 만들지 말것
      • @todo 많은 유저가 구독중인 알람으로 인한 서버부담을 줄이고자 유저를 토픽 유저를 그룹으로 나눠서 시간차로 보낼 수 있는지 확인
  • ios
    • firebase 프로젝트 설정에서 APNs 등록 필요
    • xcode 에서 push 활성화 필요할 것

firebase-admin

  • sendTo 로 시작하면 레거시 api 이므로 사용불가, send 를 사용
  • sendEachForMulticast 여러 토큰에 한번에 전송이 필요한 경우 사용

rest

fcm access token 발급

사용

  • vim rest 형태니 알아서 변경해서 쓴다
    https://fcm.googleapis.com
    
    Content-Type: application/json
    Authorization: Bearer [위에서 발급받은 accessToken]
    
    POST /v1/projects/saljiro/messages:send
    
    {
      "message": {
        "data":{
          "deepLink":"myscheme://path",
        },
        "notification":{
          "body":"1",
          "title":"leserrafim"
        },
        "token" : "[발송 대상의 fcm token]"
      }
    }
    

언급되는 라이브러리

구현

  • 유저의 디바이스가 여러개일 수 있으므로 user, token 관계는 1:n
  • 로그인을 가정
sequenceDiagram
  participant a as app
  participant u as auth
  participant b as backend
  participant f as firebase
  participant d as db
  u -->> a: login
  f -->> a: token
  a -->> b: setToken: login 정보 + device 정보
  b -->> d: 동일디바이스 기존 토큰 제거 및 신규 토큰 추가
  par 구독
    a -->> b: 구독
    b -->> f: topic*n 구독
    f -->> b: 200
    b -->> d: 200: 구독 키워드 기록
    par 실패한 토큰 처리
      b -->> d: `messaging/registration-token-not-registered`: 토큰 제거
    end
  end
  par push
    b -->> f: push 요청
    b -->> d: 4xx,5xx: 토큰 제거
    f -->> a: push notification
  end