푸시 알림 — FCM 과 Web Push
푸시 알림 — FCM 과 Web Push
모바일·웹에서 사용자가 앱을 열고 있지 않아도 메시지를 보내려면 운영체제·브라우저가 제공하는 푸시 채널을 통과해야 합니다. iOS 는 APNs, Android 는 FCM, 웹은 Web Push 표준이 그 자리에 있습니다.
1. FCM 에 대한 이야기
FCM (Firebase Cloud Messaging) 은 Google 의 푸시 메시징 서비스입니다. GCM (Google Cloud Messaging, 2012) 의 후속입니다. 2016 년 FCM 으로 브랜드 통합됐고 이후 GCM API 는 단계적으로 종료 (2018 ~ 2024) 됐습니다. 현재 권장되는 API 는 HTTP v1 입니다 (레거시 server key API 는 deprecated).
FCM 은 다음 채널을 묶습니다.
- Android — 자체 채널.
- iOS — 내부적으로 APNs 를 통해 전달.
- Web — 표준 Web Push 위에서 동작.
2. APNs 와 Web Push
APNs (Apple Push Notification service) — Apple 의 자체 채널 (2009 도입). iOS · iPadOS · macOS · watchOS · tvOS 에 메시지를 전달합니다. 인증은 토큰 기반 (JWT) 또는 인증서 기반.
Web Push — W3C · IETF 가 표준화한 브라우저 푸시. RFC 8030 (HTTP Web Push, 2016) · RFC 8291 (메시지 암호화, 2017) · RFC 8292 (VAPID, 2017). VAPID 는 발신자가 자기 신원을 푸시 서비스에 증명하는 메커니즘입니다. Chrome · Firefox · Edge · Safari 가 지원합니다 (Safari 는 16.4 / 2023 부터 macOS · iOS 16.4+).
3. 토큰 라이프사이클
① 요청 클라이언트가 푸시 권한을 사용자에게 요청
② 발급 OS · 브라우저가 토큰(또는 subscription) 발급. 앱·기기 별 고유.
③ 전달 클라이언트가 자기 백엔드에 토큰 등록
④ 사용 백엔드가 푸시 서비스에 토큰 + 메시지 페이로드 제출
⑤ 갱신 OS 가 임의로 토큰을 무효화·재발급할 수 있음
⑥ 만료 사용자가 권한을 끄거나 앱이 제거되면 토큰이 살아있어도 실패 누적
토큰은 영원하지 않습니다. 갱신·정리 흐름이 필요합니다.
4. 메시지 종류 (FCM 기준)
| 종류 | 동작 |
|---|---|
| notification | 시스템 트레이에 자동 표시. 앱이 백그라운드일 때 OS 가 처리. |
| data | 페이로드만 전달. 앱이 직접 처리. 백그라운드 처리 한계가 OS 별로 다름. |
| combined (notification + data) | 두 정보 모두. 백그라운드는 OS 가, 포그라운드는 앱이 처리. |
iOS 의 백그라운드 data-only 메시지는 content-available: 1 같은 추가 설정과 OS 의 처리 우선순위 가정에 영향을 받습니다. 신뢰성은 보장되지 않는 경우가 자주 보고됩니다.
5. 페이로드와 firebase-admin
FCM HTTP v1 페이로드 예시:
{
"message": {
"token": "<device_token>",
"notification": {
"title": "새 메시지",
"body": "확인해 주세요"
},
"data": {
"type": "chat",
"chat_id": "1234"
},
"android": { "priority": "high" },
"apns": {
"payload": {
"aps": { "sound": "default" }
}
}
}
}
Node · Python · Java · Go · .NET SDK 가 있습니다.
import { initializeApp, cert } from 'firebase-admin/app';
import { getMessaging } from 'firebase-admin/messaging';
initializeApp({ credential: cert(serviceAccountJson) });
await getMessaging().send({
token,
notification: { title, body },
data: { type: 'chat', chat_id },
});
서비스 계정 JSON 키는 시크릿입니다. 환경 변수 또는 시크릿 매니저로 관리합니다. SDK 가 OAuth2 토큰 갱신·HTTP v1 호출을 추상화합니다.
6. 자체 Web Push 서버
VAPID 키 (공개키·비공개키 쌍) 를 만들고 클라이언트는 pushManager.subscribe(...) 로 subscription 을 받습니다. 서버는 web-push (Node) · pywebpush (Python) 등의 라이브러리로 직접 푸시 서비스 (Firefox autopush · Chrome FCM 엔드포인트) 에 호출합니다. 페이로드는 ECE (RFC 8188) 로 암호화됩니다.
이 경로는 Firebase 가입 없이도 가능합니다. iOS Web Push (16.4+) 도 같은 표준을 따릅니다.
7. OneSignal 과 비교
OneSignal 은 푸시·이메일·SMS 를 묶은 매니지드 서비스 (2014) 입니다. FCM · APNs · Web Push 를 한 SDK 로 추상화합니다. 분석·세그먼테이션·A/B 가 강점으로 자주 거론됩니다. 한계는 사용자 데이터가 외부에 저장된다는 점, 무료 티어 한도입니다.
| 항목 | FCM (직접) | OneSignal | 자체 Web Push |
|---|---|---|---|
| 모바일 (iOS+Android) | 가능 (firebase-admin) | 가능 | iOS는 16.4+ 웹만 |
| 웹 | 가능 (FCM JS SDK) | 가능 | 가능 (VAPID) |
| 분석·세그먼테이션 | 기본 한정 | 강함 | 직접 구현 |
| 데이터 소유 | Google 인프라 경유 | OneSignal 경유 | 자체 + 푸시 서비스 |
| 비용 | 사용량 기반 (Google) | 티어 | 매우 저렴 |
8. 토큰 정리와 토픽
서버는 발송 결과를 받아 실패한 토큰을 정리합니다.
- FCM:
messaging/registration-token-not-registered같은 에러 → 토큰 행 삭제. - Web Push:
410 Gone또는404 Not Found→ subscription 삭제.
FCM 은 토픽 구독 모델을 제공합니다 (/topics/news). 한 번의 호출로 같은 토픽의 모든 구독자에게 보낼 수 있습니다. 다만 토픽은 사용자 수가 늘면 응답 지연이 보고됩니다. 정확한 분산이 필요하면 직접 토큰 묶음으로 보내는 batch · multicast 가 자주 쓰입니다.
9. 자주 걸리는 자리
레거시 server key API 사용 — HTTP v1 으로 이미 옮겼는지 확인합니다. 옛 GCM/FCM legacy API 는 종료된 자리입니다.
iOS data-only 의 신뢰성 — 백그라운드 데이터 전용 메시지는 OS 의 처리 정책에 흔들립니다. 표시가 필요한 알림은 notification 페이로드도 포함합니다.
서비스 워커 누락 — Web Push 는 등록된 서비스 워커가 메시지를 받습니다. PWA 가 아니어도 서비스 워커가 필요합니다.
VAPID 키 분실 — 자체 Web Push 의 키를 잃으면 기존 subscription 이 무효가 됩니다.
앱 종료 후 알림 — Android 의 일부 OEM 은 강제 종료된 앱의 백그라운드 처리를 막아 알림이 늦거나 누락될 수 있습니다.
페이로드 한도 — APNs · FCM 모두 페이로드 크기 제한 (약 4KB) 이 있습니다. 큰 데이터는 토큰만 보내고 클라이언트가 별도 API 호출합니다.
시간대 가정 — 단순 발송이 사용자 시간대를 무시하면 새벽 알림이 됩니다.
하고픈 말
푸시는 사용자 동의가 가장 어려운 단계입니다. 동의 직후 처음 받는 알림이 가치 있게 느껴지는지가 옵트아웃 비율을 결정합니다. 새벽 알림·과도한 빈도는 한 번에 권한이 닫히는 자리입니다.
Next
- image-pipeline
- backup-restore
FCM 공식 문서 · FCM HTTP v1 · APNs 공식 · RFC 8030 — HTTP Web Push · web-push npm · MDN Push API 를 참고합니다.