You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 09:01:10