FCM Token 与中台联动说明#
1. 核心结论#
FCM Token 是“某台设备上某个 App 安装实例的推送地址”。App 把 Token 上报给中台,中台保存后,才能通过 Firebase 将通知或配置刷新指令准确发送给这台设备。
FCM Token 不是用户账号,也不是永久不变的设备 ID。
| 组成部分 | 负责什么 |
|---|---|
| FCM Token | 解决“推给哪台设备” |
| 我们的中台 | 解决“推什么、什么时候推、推给哪些人” |
| Firebase Cloud Messaging(FCM) | 负责把消息从服务端送到设备 |
| Android 客户端 | 负责注册 Token、接收消息、展示通知或执行配置刷新 |
2. 完整联动流程#
用户安装并打开 App
↓
Firebase 为当前 App 安装实例生成 FCM Token
↓
App 将 Token、语言、版本、时区等信息上传到中台
↓
中台保存并维护当前有效 Token
↓
运营在中台创建通知或修改通知配置
↓
中台根据语言、国家、版本、活跃状态等条件筛选 Token
↓
中台服务端调用 FCM HTTP v1 API
↓
Firebase 将消息发送给目标设备
↓
设备直接展示通知,或通知 App 拉取最新中台配置
例如,App 可以向中台注册以下信息:
{
"installationId": "install_7f31...",
"fcmToken": "fcm_token_ABC123...",
"platform": "android",
"appVersion": "1.0.3",
"language": "en",
"country": "US",
"timezone": "America/New_York",
"notificationPermission": true
}
3. 中台建议保存的字段#
| 字段 | 作用 | 更新时机 |
|---|---|---|
installationId |
我们生成的安装实例标识 | 首次启动生成,重装后重新生成 |
fcmToken |
当前安装实例的 FCM 推送地址 | 首次获取及 Token 刷新时 |
userId |
登录后关联的用户账号,可为空 | 登录、切换账号、退出登录时 |
platform |
区分 Android / iOS | 注册时 |
appVersion |
版本筛选与配置兼容 | App 升级后 |
language |
选择对应语言文案 | App 或设备语言变化时 |
country |
国家或地区分组 | 注册及必要的资料更新时 |
timezone |
按用户当地时间发送 | 时区变化时 |
notificationPermission |
用户当前是否允许通知 | 权限状态变化及 App 启动时 |
lastActiveAt |
判断用户最近是否活跃 | App 启动或进入前台时 |
tokenUpdatedAt |
Token 最后更新时间 | Token 注册或刷新时 |
pushStatus |
正常、失效、退订等状态 | 发送结果返回后 |
中台不应只用 Token 表示用户。一个用户可能拥有多台设备,一个设备也可能切换账号:
用户账号
├── 手机 A 的安装实例 → Token A
├── 手机 B 的安装实例 → Token B
└── 平板的安装实例 → Token C
未登录用户同样可以获得 FCM Token,因此应以 installationId 为基础记录,以 userId 作为可选关联。
4. Token 为什么会变化#
以下情况可能导致 FCM Token 变化或失效:
- App 卸载后重新安装;
- 用户清除 App 数据;
- Firebase 主动刷新 Token;
- App 从系统备份恢复;
- Token 过期或被 Firebase 作废;
- 用户更换设备。
Android 客户端必须监听 Token 更新并重新上报中台:
override fun onNewToken(token: String) {
// 将最新 Token 上传到我们的中台
}
中台收到新 Token 后,应更新当前安装实例对应的旧 Token,避免同一设备保留多个重复地址。
5. 中台发送消息的安全链路#
正确链路:
运营后台
↓
我们的服务端
↓
Firebase Admin SDK / FCM HTTP v1 API
↓
用户设备
Android 客户端不能直接持有并调用 FCM 服务端发送凭证。Firebase 服务账号、私钥和访问令牌只能保存在服务端安全环境中,禁止放入:
- APK;
- Git 仓库;
- 中台前端网页;
- Remote Config;
- 中台下发给客户端的自定义配置字段。
6. 两种联动方式#
6.1 中台通过 FCM 直接发送通知#
中台向 FCM 提交完整通知内容:
{
"notification": {
"title": "Welcome back",
"body": "Review unnecessary files and keep your phone organized."
},
"data": {
"route": "home",
"campaignId": "welcome_001"
}
}
适合临时运营、节日、版本更新、立即召回等需要及时送达的通知。
客户端必须只接受预先定义的合法路由,不能让中台参数任意启动组件或打开不受信任地址。
6.2 FCM 只发送“刷新配置”指令#
FCM 仅发送轻量信号:
{
"data": {
"type": "config_refresh",
"configVersion": "12"
}
}
客户端收到后执行:
收到 FCM
↓
比较本地配置版本
↓
请求我们的中台
↓
下载完整通知配置
↓
校验并保存配置
↓
取消受影响的旧任务
↓
按照新配置重新安排本地通知
这种方式适合更新定时通知、多语言文案、频控、开关和路由。配置真源始终保留在中台,便于审计、回滚和紧急停发。
7. 推荐的组合方案#
两种模式可以同时使用:
| 场景 | 推荐方式 |
|---|---|
| 即时运营通知 | 中台通过 FCM 直接发送 |
| 长期定时通知策略 | FCM 通知客户端刷新中台配置 |
| App 正常启动或恢复前台 | 客户端主动检查配置版本 |
| 低频配置补同步 | WorkManager 定期检查,但不保证准点 |
| 网络不可用 | 使用本地最后一份有效配置,恢复网络后再同步 |
| 紧急停发 | 中台关闭总开关,同时发送配置刷新信号 |
最终链路:
App 获取或刷新 FCM Token
↓
Token 注册到我们的中台
↓
中台保存 Token、语言、版本、时区等信息
↓
中台修改通知配置
↓
FCM 发送 config_refresh
↓
App 重新拉取并校验配置
↓
客户端按设备语言和频控安排本地通知
或者:
中台创建即时通知
↓
筛选目标 Token
↓
FCM 直接推送
↓
系统展示通知
↓
用户点击进入指定页面
8. 登录、退出与隐私边界#
退出登录时不一定需要删除 Token,但必须解除 Token 与原账号的关联。
必须遵守以下边界:
- 退出后的设备不得继续收到原账号的私人消息;
- 是否继续接收通用运营通知,应由产品规则和用户通知设置决定;
- Token 只用于消息触达和必要的设备实例管理,不作为跨产品追踪标识;
- 服务端日志和运营页面应限制 Token 的完整展示;
- 用户关闭通知或撤回相关授权后,中台应同步更新可触达状态。
9. 发送失败与失效清理#
中台调用 FCM 成功,只表示 Firebase 接受了请求,不代表用户一定看到通知。
建议记录以下漏斗:
目标设备数
→ 提交 FCM 成功
→ Firebase 接收
→ 设备送达
→ 通知展示
→ 用户点击
→ 页面打开
Firebase 返回 Token 无效、安装实例注销等明确错误时,中台应将 Token 标记失效并停止重复发送。否则会造成:
- 无效请求持续增长;
- 推送成功率统计失真;
- 同一设备出现重复记录;
- 浪费服务端和运营资源。
10. 必须明确的系统限制#
- FCM 依赖网络、设备系统策略和 Google Play 服务,不能保证每条消息立即送达;
- 用户强制停止 App 后,消息和后台任务可能无法正常工作,直到用户再次打开 App;
- Android 13 及以上需要用户授予通知权限,Token 存在不等于通知能够展示;
- 普通优先级消息在 Doze(休眠模式)下可能延迟;
- 高优先级 FCM 应用于需要及时产生用户可见结果的消息,不能作为无限制后台保活手段;
- FCM 回调只适合短时间处理,较长的同步应转交 WorkManager。
11. 验收清单#
| 验收项 | 通过标准 |
|---|---|
| 首次注册 | 新安装实例能获取 Token 并成功登记到中台 |
| Token 刷新 | onNewToken 触发后中台替换旧 Token,不产生重复有效记录 |
| 多设备 | 同一账号的不同安装实例可以分别接收消息 |
| 退出登录 | 退出后的设备不再收到原账号私人消息 |
| 权限关闭 | 用户关闭通知权限后,中台可触达状态得到更新 |
| 直接通知 | 后台发送后,符合条件且已授权的设备可以展示通知 |
| 配置刷新 | 收到 config_refresh 后只在版本更新时拉取并替换配置 |
| 路由安全 | 非法或未知路由被拒绝,并降级进入安全默认页面 |
| 失效清理 | FCM 返回明确无效错误后 Token 被停用 |
| 数据统计 | 可以区分“提交成功、送达、展示、点击和页面打开” |
| 降级处理 | 断网或拉取失败时继续使用最后一份校验通过的配置 |
| 紧急停发 | 中台关闭总开关后,不再产生新的计划通知 |