Flutter应用杀死重启后FCM Token变更,导致推送消息无法接收如何解决
Flutter FCM Token重启应用后变更的原因及解决办法
可能的原因
- 签名/证书不一致:调试和正式环境用了不同签名证书,或者证书更新过,FCM会判定为不同应用实例,重启后生成新Token。
- 存储权限缺失:FCM需要将Token持久化到设备本地,若应用未获取存储权限,重启后无法读取旧Token,只能重新生成。
- SDK版本bug:部分旧版
firebase_messagingSDK存在重启后重复生成Token的问题,Android平台尤为明显。 - 应用数据被清理:系统或第三方清理工具在应用杀死后清理了缓存/数据,FCM存储的Token丢失,重启后需重新生成。
- Android 13+通知权限问题:Android 13及以上需单独申请
POST_NOTIFICATIONS权限,未授予时可能导致FCM重启后刷新Token。
解决办法
- 统一签名配置:确保调试、正式环境使用相同签名证书,在
android/app/build.gradle中固定签名信息,避免环境差异引发Token变更。 - 申请存储权限:在AndroidManifest.xml中添加存储权限(旧版Android需
READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE),并在应用启动时主动申请,保证FCM能持久化Token。 - 更新Firebase SDK:将
firebase_messaging等依赖升级到最新稳定版,修复已知的Token重复生成bug。 - 手动持久化Token:获取到Token后,存入SharedPreferences或Hive等本地存储,重启时优先读取本地Token,不存在再调用
getToken()。示例代码:
import 'package:shared_preferences/shared_preferences.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; Future<String?> getFCMToken() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? savedToken = prefs.getString('fcm_token'); if (savedToken != null) { return savedToken; } String? newToken = await FirebaseMessaging.instance.getToken(); if (newToken != null) { await prefs.setString('fcm_token', newToken); } return newToken; }
- 监听Token刷新事件:通过
onTokenRefresh监听Token变更,及时同步到后端服务器,并更新本地存储。示例代码:
import 'package:shared_preferences/shared_preferences.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async { // 同步新Token到后端 updateTokenOnServer(newToken); // 更新本地存储 SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString('fcm_token', newToken); }); // 自行实现后端同步逻辑 void updateTokenOnServer(String token) { // 你的API请求代码 }
- 申请Android 13+通知权限:在AndroidManifest.xml添加
POST_NOTIFICATIONS权限,启动时主动请求权限。示例代码:
import 'package:permission_handler/permission_handler.dart'; Future<void> requestNotificationPermission() async { if (await Permission.notification.isDenied) { await Permission.notification.request(); } }
内容的提问来源于stack exchange,提问作者Tabarek Ghassan
相关产品推荐
相关产品推荐

