Flutter中调用FCM的deleteToken后如何获取新设备令牌?
FCM登出后deleteToken仍返回旧令牌的解决方案
问题根源
调用deleteToken()后,FCM仅解除了当前令牌与应用实例的云端关联,但客户端本地缓存的旧令牌并未被清除;而getToken()默认会优先返回本地缓存的令牌,不会主动生成新令牌,导致再次登录时拿到旧值。
解决步骤
1. 登出时彻底清除本地令牌缓存
调用deleteToken()成功后,手动删除本地存储的令牌(比如Android的SharedPreferences、iOS的UserDefaults),避免后续getToken()读取缓存值。
Android示例:
FirebaseMessaging.getInstance().deleteToken().addOnCompleteListener { task -> if (task.isSuccessful) { // 清除SharedPreferences中的令牌缓存 val fcmPrefs = getSharedPreferences("FCM_CACHE", Context.MODE_PRIVATE) fcmPrefs.edit().remove("saved_token").apply() } }
iOS示例:
Messaging.messaging().deleteToken { error in guard error == nil else { return } // 清除UserDefaults中的令牌缓存 UserDefaults.standard.removeObject(forKey: "FCM_SAVED_TOKEN") }
2. 再次登录时强制获取新令牌
不要直接调用getToken(),而是先确保旧令牌已彻底解除关联,再触发新令牌的生成:
Android方案:
先调用deleteToken()确保云端关联解除,再获取新令牌:
FirebaseMessaging.getInstance().deleteToken() .addOnSuccessListener { // 获取新令牌 FirebaseMessaging.getInstance().token.addOnSuccessListener { newToken -> // 将新令牌上传到服务器绑定当前用户 uploadTokenToServer(newToken) } }
iOS方案:
同样先删除旧令牌关联,再请求新令牌:
Messaging.messaging().deleteToken { error in guard error == nil else { return } Messaging.messaging().token { newToken, error in guard let token = newToken, error == nil else { return } // 上传新令牌到服务器 uploadTokenToServer(token) } }
3. 同步服务器端逻辑
登出时,服务器需立即将该用户关联的旧令牌标记为无效;再次登录时,将新令牌与用户账号绑定,避免服务器仍向旧令牌发送通知。
额外注意
- 部分场景下,FCM可能会延迟生成新令牌,可通过设置
TokenRefreshListener(Android)或messagingDelegate(iOS)监听令牌自动刷新事件,确保及时获取新值。 - 测试时需彻底重启应用,避免内存中残留的旧令牌影响结果。
内容的提问来源于stack exchange,提问作者Moony-Stary
相关产品推荐
相关产品推荐

