본문으로 건너뛰기

모바일 푸시

APNs(iOS)·FCM v1(Android)로 푸시를 보낸다. SDK 없이 키로 서명하고, 기기별 결과를 돌려주며, 앱이 지워진 기기는 「받는 쪽이 영구히 없다」로 따로 알려 토큰을 지우게 한다

npm install @duolabs-deux/unit-push

직접 넣어 보기

기기(가상)
제목

환경변수

이름설명
APNS_KEY_ID선택APNs 키의 Key ID. iOS 로 보낼 때
APNS_TEAM_ID선택Apple 팀 ID
APNS_PRIVATE_KEY_B64선택.p8 파일 내용을 base64 로(여러 줄 PEM 이 환경변수에서 깨지지 않게). 소비 앱이 풀어서 넘긴다
FIREBASE_SERVICE_ACCOUNT_B64선택FCM 서비스 계정 JSON 을 base64 로. Android 로 보낼 때

어댑터

id종류설명
apns실제APNs 토큰 인증(ES256). HTTP/2 를 말하는 fetch 를 소비 앱이 넣는다. BadDeviceToken 이면 반대쪽 게이트웨이로 한 번
fcm실제FCM HTTP v1. 서비스 계정 RS256 JWT 로 OAuth 토큰을 받아 캐시한다
fake가짜키 없이 결정적으로 답한다. 토큰에 든 낱말(gone·wrong·quota·down·slow)로 실패를 재현한다

실패와 소비 앱이 할 일

종류언제할 일
invalid-input메시지 형식이 틀렸을 때(data 값이 문자열이 아님 등), 토큰 모양이 틀렸을 때. 밖으로 나가지 않는다보내는 쪽 코드를 고친다
invalid-input받는 쪽이 영구히 없을 때(앱 삭제·토큰 무효·다른 앱의 토큰). recipientGone() 이 이유를 준다그 토큰을 지운다. 다시 보내도 같다
authAPNs 키·FCM 서비스 계정이 틀렸거나 폐기됐을 때운영자에게 알린다. 푸시 실패로 본 기능을 실패시키지 않는다
quota발송 한도에 걸렸을 때. 같은 플랫폼의 남은 기기는 보내지 않고 skipped 로 돌려준다retryAfterMs 뒤에 그 기기들만 다시 보낸다
timeout응답이 8초 안에 없을 때. 이미 갔을 수 있어 다시 보내지 않는다중복을 감수할 수 있으면 다시 보낸다
upstream-downAPNs·FCM 서버 오류. 다시 보내지 않는다timeout 과 같다

한도

  • 본문(알림·데이터)은 4KB 까지
  • APNs 는 HTTP/2 만 받는다. Node 의 기본 fetch 로는 닿지 않는다
  • Expo 푸시 서비스(ExponentPushToken)는 다루지 않는다. 기기 고유 토큰만 받는다
  • 웹 푸시(VAPID)는 다루지 않는다

명세