01 · FCM 核心概念与架构¶
目标读者:需要建立 Firebase Cloud Messaging 心智模型的所有人 核心问题:一条推送从我的脚本到玩家手机,中间到底经过了什么?每个概念到底指什么? 前置:无 后续: 02-HTTP-v1-API与认证 最后更新:2026-04-11
一、FCM 是什么¶
Firebase Cloud Messaging (FCM) 是 Google 提供的跨平台免费消息推送服务。能零成本地把通知或数据消息从你的服务器送达 Android、iOS、Web、Flutter 应用。
- 前身:GCM (Google Cloud Messaging),2016 年并入 Firebase
- 定位:Firebase 套件里的核心模块,与 Auth / Firestore / Functions / Analytics 等并列
- 对运营的意义:群发推送的"水电煤" —— 免费、官方、稳定、全球可达
Firebase 全家桶
┌────────────────────────────────────┐
│ Auth Firestore RTDB Storage │
│ Functions Hosting Analytics │
│ Crashlytics Remote Config │
│ ┌──────────────────────────────┐ │
│ │ Cloud Messaging (FCM) ⬅️ 本节主题 │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
关键事实:你不需要用 Firestore / Auth 才能用 FCM。只要创建一个 Firebase Project 即可。对 iGaming 运营自动化场景,只需要 FCM 一个产品。每个平台对应一个独立的 Firebase Project(因为它们是不同的 App、不同的包名、不同的 APNs 证书)。
二、三大组件¶
FCM 的工作链路由三个角色构成:
┌──────────────┐ ┌────────────────┐ ┌──────────────┐
│ App Server │ ─────► │ FCM Backend │ ─────► │ App Client │
│ │ │ │ │ │
│ 你的后端/脚本 │ HTTPS │ Google 运营的 │ 推送 │ 终端设备上的 │
│ (可自动化) │ │ 全球消息中转 │ │ App(Android │
│ │ │ │ │ iOS/Web) │
└──────────────┘ └────────────────┘ └──────────────┘
↑ │ ↑
│ ▼ │
│ 对接 APNs / Android │
│ 长连接 / Web Push │
│ │
└──────────────────── 拿到 token ◄──────────────────┘
(SDK 自动注册)
2.1 App Client(应用客户端)¶
装在终端用户设备上的 App (Android / iOS / Web),通过 FCM SDK 向 FCM 注册并获得注册令牌 (Registration Token),负责接收并展示消息。
2.2 FCM Backend(FCM 后端)¶
Google 自己运营的全球消息中转服务。你的服务器只跟它打交道,它负责对接: - Apple APNs(Apple 推送服务),处理 iOS 推送 - Android 长连接,处理 Android 推送 - Web Push 协议,处理浏览器推送
这是免费的、由 Google 维护的中间层。Apple 的推送服务复杂且证书一年一换,FCM 帮你封装了这些细节。
2.3 App Server(应用服务器 / Trusted Environment)¶
你自己的后端 —— 发起推送请求的地方。可以是: - Node.js 脚本 - Python cron job - Cloud Functions / Cloud Run - 本地一次性脚本 - Docker + cron 容器
运营自动化脚本就跑在这一层。
2.4 三者交互流程¶
[App Server(你)] [FCM Backend(Google)] [App Client(设备)]
1) 拿 Service Account
签 JWT → 换 OAuth Token
2) POST messages:send ──────► 3) 收到请求,校验,入队
body = { message: {...} }
4) 收到 200 + 消息 ID ◄──────
5) 路由到 APNs / Android FCM
长连接 / Web Push
────► 6) 系统/SDK 弹通知
7) 用户点击 → App 处理
关键事实:
1. App Server 永远不直接连设备。只跟 fcm.googleapis.com 打 HTTPS。
2. 消息一旦提交到 FCM,FCM 会保证投递(设备在线 → 立即;离线 → 缓存最多 4 周,TTL 默认 4 周可改)。
3. 你完全不需要自己维护 APNs 证书、Web Push VAPID、Android 长连接。
三、Registration Token(注册令牌)详解¶
别名:FCM Token、Device Token、注册令牌
3.1 基本事实¶
| 属性 | 说明 |
|---|---|
| 生成 | App 集成 FCM SDK 后,首次启动时 SDK 自动调用 FirebaseMessaging.getInstance().getToken() 得到 |
| 长度 | 约 163 字符的长字符串 |
| 唯一性 | 每个 (App 包名 × 设备 × 安装实例) 唯一 |
| 用途 | 服务器拿着它就能精准推送给某一台设备 |
3.2 生命周期¶
通常稳定数月。但下列情况会失效或变化:
| 触发场景 | 结果 |
|---|---|
| 用户卸载 App | Token 失效 |
| 用户清空 App 数据(Android) | Token 换新 |
| 用户在新设备恢复 | Token 换新 |
| 用户明确删除 token | 失效 |
| App 几个月没启动 | FCM 主动失效 |
| Token 自动轮转(罕见) | 换新 |
3.3 管理建议(后端视角)¶
客户端 App
│
│ onTokenRefresh() 监听 + 每次启动也上报
▼
你的后端 API
│
│ 去重 UPSERT
▼
数据库表 fcm_tokens
│
│ (user_id, fcm_token, platform, app_version, updated_at)
▼
定期清理:
· 服务端发推送时收到 UNREGISTERED / NOT_FOUND → 立刻删
· 超过 2 个月未活跃的 token → 定期清理
3.4 失效处理(非常重要)¶
服务端发推送时,如果收到下列错误:
- UNREGISTERED (HTTP 404)
- NOT_FOUND
- INVALID_ARGUMENT(token 格式已不合法)
必须从数据库删除该 token,否则会越积越多,影响后续批量发送效率。详细处理见 06-错误处理与Token生命周期。
四、Topic(主题)详解¶
Topic 是 发布/订阅模式 的"频道"。设备订阅某个 topic,服务器对这个 topic 发一条消息,所有订阅者都收到。
对运营批量推送 = 完美工具。
4.1 订阅方式¶
方式 A:客户端订阅
// Android
FirebaseMessaging.getInstance().subscribeToTopic("all_users")
// iOS
Messaging.messaging().subscribe(toTopic: "all_users")
方式 B:服务端订阅(绕过客户端) ⭐
用 Admin SDK 批量把一组 token 订阅到某个 topic:
await admin.messaging().subscribeToTopic([token1, token2, ...], 'all_users');
这对运营自动化非常关键 —— 你可以批量把所有玩家 token 订阅到 all_users,之后每次推送只需调用一次 API 发到 topic,FCM 会自动扇出给所有订阅者。
4.2 命名规范¶
- 允许字符:
[a-zA-Z0-9-_.~%]+ - 长度 ≤ 900 字符
4.3 限额¶
- 每个 App 可订阅的 topic 数:无限制
- 单个 token 同时订阅的 topic 数:约 2000
- Topic 扇出速率:默认 每分钟 10,000 条 fan-out(可申请提升)
- 订阅生效延迟:约 1 分钟内(订阅后不是立刻生效)
4.4 Condition(条件目标)¶
发消息时可以写一个表达式,把多个 topic 用 && || ! 组合:
"'all_users' in topics && ('vip_users' in topics || 'high_value' in topics)"
- 最多组合 5 个 topic
- 典型场景:给 VIP 用户 ∩ iOS 设备 发定制推送
五、消息类型对比¶
FCM 消息有三种类型,选对类型对 iGaming 场景至关重要:
| 类型 | notification 字段 | data 字段 | App 在前台 | App 在后台 | 典型用途 |
|---|---|---|---|---|---|
| Notification only | ✅ | ❌ | onMessageReceived 回调,App 自己处理 |
系统自动弹通知 | 简单推送 |
| Data only | ❌ | ✅ | onMessageReceived 回调 |
onMessageReceived 回调(Android) / 静默推送(iOS 需 content-available) |
静默更新、自定义 UI |
| Hybrid ⭐ | ✅ | ✅ | onMessageReceived 回调 |
系统弹通知 + data 进 intent extras | 推荐方式 |
5.1 iGaming 推送的最佳实践¶
对于"推送优惠码"这种场景,Hybrid 模式最实用:
{
"notification": {
"title": "限时优惠码 SUPER88",
"body": "今晚 11 点前充值送 88% 红利"
},
"data": {
"promo_code": "SUPER88",
"deeplink": "myapp://promo/super88",
"campaign_id": "2026-04-11-night"
}
}
notification保证后台时系统自动弹data保证前台时 App 能拿到优惠码和 deeplink
六、目标方式对比¶
| 方式 | 字段 | 用法 | 适用 |
|---|---|---|---|
| Single device | token: "xxx..." |
单次 send() |
给一个设备,最精准 |
| Multiple devices | tokens: [...] (≤500) |
sendEachForMulticast() |
给一批指定设备 |
| Topic ⭐ | topic: "all_users" |
单次 send() |
群发,所有订阅者 |
| Condition | condition: "'A' in topics && 'B' in topics" |
单次 send() |
群发交集/并集 |
| Device group(已废弃) | — | — | Legacy API 概念,v1 不再推荐 |
6.1 Token vs Topic 选型决策树¶
要推送多少用户?
│
├─ < 500 → sendEachForMulticast(tokens)
│
├─ 500 ~ 几千 → 循环 sendEachForMulticast(每批 500)
│ 或 预先订阅 topic 后一次发送
│
└─ 几千 ~ 百万 → 预先订阅 topic,然后 send(topic)
(1 次 API 调用搞定)
iGaming 运营场景的黄金答案:预先把所有玩家 token 订阅到 all_users topic,之后每次推送只调 1 次 API。这把"5 次 × N 平台 × M 用户"压缩到了"5 次 × N 平台"。
七、限额与吞吐(重点关注)¶
| 项目 | 限额 |
|---|---|
| 单条消息 payload | 4 KB(Notification + Data 合计) |
| HTTP v1 API 单请求 | 1 条消息 |
| sendEach / sendEachForMulticast | 每次最多 500 个 token,SDK 内部并发拆分 |
| Topic fan-out 速率 | 默认 每分钟 10,000 条(可申请提升) |
| 每项目 messages.send QPS | 默认很高(数千 QPS),未公开硬限 |
| Topic 订阅 API | 每 token 每秒 ≤ 3,000 次 batch operation |
| 消息 TTL | 默认 4 周,可设 0 ~ 2,419,200 秒 |
八、常见陷阱(先看再写代码)¶
-
Legacy API 已废弃 ⚠️ 2024-06-20 Google 正式停用基于 server key 的
https://fcm.googleapis.com/fcm/send端点。任何老代码(包括教程、GitHub 抄来的)基于 server key 的都跑不通了。必须用 HTTP v1 + Service Account(详见 02)。 -
iOS 必须配 APNs Authentication Key 需要在 Firebase Console 上传 .p8 文件,否则 iOS 永远收不到。Android 不用。
-
iOS 静默推送需
content-available: 1且 1 小时内系统会限频,不要滥用。 -
Notification message 在 App 前台时不会自动弹 必须在
onMessageReceived里自己处理展示。 -
Topic 订阅有延迟 订阅后到生效约 1 分钟内,写测试要 sleep。
-
Token 失效必须从数据库删 不清理会导致后续批量发送效率雪崩。
九、与本系列其它文档的关系¶
| 要做什么 | 看哪份 |
|---|---|
| 学认证、写 curl 发第一条推送 | 02-HTTP-v1-API与认证 |
| 用 Node/Python 代码发推送 | 03-Admin-SDK实战 |
| 批量发给一批 token / 一个 topic | 04-批量发送与广播模式 |
| 搞懂 notification vs data、Android/iOS 平台字段 | 05-消息载荷与平台定制 |
| 处理失败 token、重试策略 | 06-错误处理与Token生命周期 |
| 选定时方案(cron / Cloud Scheduler / ...) | 07-定时与调度方案 |
| 落地"一次发 N 个平台"的完整架构 | 08-iGaming多平台批量推送实战 |
十、权威来源¶
- https://firebase.google.com/docs/cloud-messaging
- https://firebase.google.com/docs/cloud-messaging/concept-options
- https://firebase.google.com/docs/cloud-messaging/manage-topics
- https://firebase.google.com/docs/cloud-messaging/manage-tokens