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

如何使用StreamController实现Flutter推送通知的页面实时更新

前置准备
  • 先完成firebase_messaging的基础配置,在pubspec.yaml中引入依赖:
    firebase_messaging: ^14.6.1(版本可根据项目适配情况调整)
实现步骤
  • 第一步:创建全局广播Stream控制器,用于跨页面传递FCM推送数据
import 'dart:async';

// 全局单例控制器,broadcast类型支持多个页面同时监听
final StreamController<Map<String, dynamic>> fcmMessageStream = StreamController<Map<String, dynamic>>.broadcast();
  • 第二步:在FCM的全场景回调中注入推送数据到Stream
    需要覆盖前台接收、后台点击通知打开应用、应用终止后点击通知打开应用三种场景:
import 'package:firebase_messaging/firebase_messaging.dart';

// 应用初始化时调用这段配置
void initFCMListener() async {
  // 1. 前台收到推送时触发
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    fcmMessageStream.add(message.data);
    // 可补充前台通知弹窗逻辑
  });

  // 2. 后台挂起状态下点击通知打开应用时触发
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    fcmMessageStream.add(message.data);
  });

  // 3. 应用完全终止状态下点击通知打开应用时触发
  RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
  if (initialMessage != null) {
    fcmMessageStream.add(initialMessage.data);
  }
}
  • 第三步:页面层监听Stream更新UI
    推荐直接使用StreamBuilder组件,框架会自动处理监听的生命周期:
@override
Widget build(BuildContext context) {
  return StreamBuilder<Map<String, dynamic>>(
    stream: fcmMessageStream.stream,
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        final pushData = snapshot.data!;
        // 此处根据业务需求更新UI,比如刷新消息列表、跳转指定页面
        return Text("新推送内容:${pushData['content'] ?? '无内容'}");
      }
      return const Text("暂无新推送");
    },
  );
}
注意事项
  • 如果手动调用stream.listen()做自定义逻辑,需要保存返回的StreamSubscription实例,在页面dispose生命周期中调用cancel()方法释放资源,避免内存泄漏;使用StreamBuilder无需额外处理,框架会自动销毁监听。
  • 确保全局只有一个fcmMessageStream实例,FCM回调和页面监听必须使用同一个控制器才能正常接收数据。
  • 如果需要新监听者加入时能获取到最近一次的推送数据,可以引入rxdart包,用BehaviorSubject替代默认的StreamController。

内容的提问来源于stack exchange,提问作者Shammah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:06:03