咨询FCM令牌失效原因及删除后重获令牌无法推送的刷新方法
嘿,我来帮你拆解下FCM令牌的问题,之前我也踩过类似的坑,给你详细说说:
FCM令牌失效的常见原因
首先,先聊聊令牌失效的几个核心场景,这些都是实际开发和官方规范里的高频情况:
- 应用被卸载:这是最普遍的原因,用户卸载App后,FCM会自动将对应的令牌标记为失效状态
- 应用数据被清除:如果用户手动清除了App的缓存或全部数据,令牌会直接失效
- 长期未与FCM通信:设备长时间离线,或者App超过30天没有和FCM服务器交互,令牌可能被系统回收
- 应用签名/版本变更:当你更新了App的签名证书,或者做了涉及身份验证的版本升级,旧令牌会因为身份不匹配失效
- 设备系统变更:比如设备恢复出厂设置、刷机,或者切换了设备上的用户账户,令牌绑定的设备环境被破坏,导致失效
- 主动调用删除方法:如果代码里主动调用了
deleteToken()这类方法,旧令牌会被直接标记为未注册
解决删除令牌后新令牌无法使用的问题&正确刷新令牌的步骤
你遇到的情况很典型:删除旧令牌后,SDK返回的新令牌看起来和旧的一样,但FCM提示未注册。这是因为FCM会缓存令牌信息,即使你删除了,短时间内返回的可能是同一个标识,但这个标识已经被标记为无效了。下面是正确的处理方式:
1. 停止在每个页面加载时获取令牌
频繁在页面加载时调用getToken()是大忌——这会导致FCM返回缓存的无效令牌,还会增加不必要的服务器请求。应该只在**应用初始化时(比如首页首次加载)**调用一次,后续靠SDK的监听事件处理令牌刷新。
2. 正确监听令牌刷新事件
FCM SDK本身会自动监听令牌的变化,你不需要主动轮询。以Web端为例,正确的监听方式是:
// 应用初始化时执行一次 async function initFCMToken() { try { // 请求通知权限(如果还没授权) const permission = await Notification.requestPermission(); if (permission !== 'granted') { console.log('用户未授权通知权限'); return; } // 获取当前令牌 const currentToken = await messaging.getToken({ vapidKey: '你的VAPID密钥' }); if (currentToken) { // 同步令牌到你的后端服务器 await syncTokenToBackend(currentToken); } // 监听令牌刷新事件 messaging.onTokenRefresh(async () => { const refreshedToken = await messaging.getToken({ vapidKey: '你的VAPID密钥' }); console.log('FCM令牌已刷新:', refreshedToken); // 立即同步新令牌到后端 await syncTokenToBackend(refreshedToken); }); } catch (error) { console.error('处理FCM令牌出错:', error); } } // 只在应用启动时调用一次 initFCMToken();
3. 主动删除令牌后的处理流程
如果你主动调用了deleteToken(),请按以下步骤操作:
- 调用
deleteToken()后,等待1-2秒(给FCM服务器同步状态的时间) - 调用
getToken()获取全新的令牌,这时候的令牌会是真正的新标识(不会和旧的重复) - 立即将新令牌同步到你的后端服务器,替换掉旧的令牌记录
- 等待几分钟再测试发送消息,确保FCM服务器已完成新令牌的注册
4. 处理报错的后端逻辑
当收到The provided registration token is not registered错误时,你的后端应该立即从数据库中移除这个令牌,避免后续再发送消息到无效令牌,同时也能减少不必要的错误日志。
额外排查点
如果按上面的步骤操作后还是报错,可以试试:
- 卸载并重新安装App,这会强制FCM生成一个完全全新的令牌
- 检查你的FCM项目配置是否正确(比如VAPID密钥、项目ID是否匹配)
- 确认后端发送消息时使用的是最新的令牌,没有缓存旧数据
内容的提问来源于stack exchange,提问作者Ashit Vora
相关产品推荐
相关产品推荐

