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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:11:41