FCM Web端主题订阅与令牌刷新相关技术问题咨询
FCM主题订阅与令牌刷新问题解答
嘿,我来帮你逐个解决这些FCM主题订阅的实际问题,都是开发中很容易踩坑的点:
问题1:如何确保订阅者始终能收到通知?
核心就是及时处理令牌刷新,并同步到服务器重新订阅主题。具体可以这么做:
- 在前端通过
onTokenRefresh监听令牌刷新事件,一旦触发就获取新令牌,立刻发送给你的服务器; - 服务器收到新令牌后,直接调用FCM的主题订阅API(
https://iid.googleapis.com/iid/v1/IID_TOKEN/rel/topics/TOPIC_NAME),不用纠结旧令牌的状态——FCM会自动处理新旧令牌的关联,旧令牌会被标记为无效; - 另外,建议在用户每次打开你的站点时,也主动获取当前令牌,和服务器存储的对比,如果不一致就重新发送并订阅,避免因为
onTokenRefresh没触发(比如用户长时间没打开站点)导致的令牌过期问题。
问题2:onTokenRefresh方法在浏览器关闭或电脑关机时是否会触发?以及如何模拟令牌刷新操作?
你说得没错,onTokenRefresh在浏览器关闭或电脑关机时完全不会触发,这个事件只有当浏览器处于活跃状态(至少打开了你的站点页面)时,FCM发现令牌需要刷新才会触发。
模拟令牌刷新的方法很简单,有两种常用方式:
- 前端手动调用
messaging.deleteToken()删除当前令牌,然后刷新页面,FCM就会自动生成新令牌并触发onTokenRefresh; - 在Chrome开发者工具里,进入
Application面板,找到Service Workers,点击Clear storage里的Clear site data,清除站点的缓存和SW数据,重新加载页面后也会触发令牌刷新。
问题3:同一令牌仅需订阅一次,但无法判断当前令牌是否已过期、是否需要为用户重新订阅,这种情况该如何处理?
其实不用刻意去判断令牌是否过期,用这两个思路就能解决:
- 无脑重新订阅:不管令牌是新获取的还是刷新来的,都直接让服务器调用FCM的订阅API。FCM允许同一个令牌重复订阅同一个主题,不会报错,只会更新主题关联记录,这样就不用担心漏订阅;
- 服务器端清理无效令牌:当你通过FCM发送通知时,如果收到
invalid_registration或NotRegistered的错误响应,就说明对应的令牌已经失效,直接从数据库里移除这个令牌即可,后续不再用它发送通知; - 额外小技巧:可以在服务器端给每个令牌记录最后更新时间,定期(比如每月)对长时间没更新的令牌进行一次重新订阅校验,或者直接删除后等待用户下次访问时重新获取令牌。
补充前端代码示例(包含令牌刷新监听)
var messaging = firebase.messaging(); messaging.useServiceWorker(reg); // 请求通知权限并获取初始令牌 messaging.requestPermission() .then(() => { return messaging.getToken(); }) .then(currentToken => { if (currentToken) { // 发送初始令牌到服务器订阅主题 $.ajax({ type: 'POST', url: URL_TO_SERVER_METHOD, data: { token: currentToken } }); } }) .catch(err => { console.error('请求权限或获取令牌失败:', err); }); // 监听令牌刷新事件 messaging.onTokenRefresh(() => { messaging.getToken() .then(newToken => { console.log('令牌已刷新,正在同步到服务器:', newToken); // 发送新令牌到服务器重新订阅 $.ajax({ type: 'POST', url: URL_TO_SERVER_METHOD, data: { token: newToken } }); }) .catch(err => { console.error('获取刷新后的令牌失败:', err); }); });
内容的提问来源于stack exchange,提问作者Alexandr Rypun
相关产品推荐
相关产品推荐

