Flutter中如何仅在用户登录时接收Firebase云消息
解决Flutter FCM用户登出后仍接收消息的问题
嘿,我来帮你搞定这个问题!你现在的核心需求是让用户登出后不再收到FCM推送,对吧?其实关键要做两件事:在消息回调里判断登录状态,避免处理未登录时的消息;同时在登出时删除设备令牌,让Firebase停止向该设备推送。
第一步:给FCM回调加登录状态校验
首先,你可以在现有的_firebaseMessaging.configure回调里,先检查用户是否处于登录状态,只有登录了才处理消息。这样就算登出后收到消息,也不会触发弹窗或页面跳转。
示例代码:
void initFCMListeners() { _firebaseMessaging.configure( onMessage: (Map<String, dynamic> message) async { // 先判断用户是否已登录 if (await _isUserLoggedIn()) { print("onMessage: $message"); _showItemDialog(message); } }, onBackgroundMessage: myBackgroundMessageHandler, onLaunch: (Map<String, dynamic> message) async { if (await _isUserLoggedIn()) { print("onLaunch: $message"); _navigateToItemDetail(message); } }, onResume: (Map<String, dynamic> message) async { if (await _isUserLoggedIn()) { print("onResume: $message"); _navigateToItemDetail(message); } }, ); } // 封装检查登录状态的方法,直接用Firebase Auth判断就行 Future<bool> _isUserLoggedIn() async { return FirebaseAuth.instance.currentUser != null; }
第二步:登出时删除FCM令牌
光在前端过滤还不够,因为Firebase还是会把消息推送到设备。所以登出时一定要删除设备的FCM令牌,这样Firebase就找不到这个设备了,自然不会再推送。
示例登出方法:
Future<void> handleLogout() async { // 1. 先完成Firebase Auth登出 await FirebaseAuth.instance.signOut(); // 2. 删除当前设备的FCM令牌 await _firebaseMessaging.deleteToken(); // (可选)如果用了本地缓存记录登录状态,同步更新 // SharedPreferences prefs = await SharedPreferences.getInstance(); // await prefs.setBool('isLoggedIn', false); }
关于后台消息的额外说明
onBackgroundMessage是在独立的隔离进程里运行的,没法直接访问App的登录状态。所以最好配合你的后端一起处理:用户登出时,不仅删除本地令牌,还要在后端数据库里把该令牌和用户的关联关系移除。这样后端发送消息时,就不会再把消息推送给这个已经登出的设备了。
另外,用户下次登录时,记得重新调用initFCMListeners(),并且获取新的FCM令牌,再把新令牌和用户重新关联到后端哦。
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

