Flutter中使用Pusher实现离线状态下接收通知的方案咨询
解决Pusher在APP彻底关闭时无法接收通知的问题
老哥,你遇到的这个问题其实是WebSocket的天生限制导致的——当APP被彻底清后台(进程直接终止)时,Pusher的WebSocket连接直接就断了,自然没法收到实时消息。要搞定这个场景的通知,你得结合系统级推送服务来实现,因为推送服务是系统层面维护的长连接,不受APP进程状态影响。下面给你具体的实现思路和步骤:
核心逻辑
Pusher的WebSocket适合APP在前台/后台(进程还活着)时的实时通信,但进程一没,WebSocket就撑不住了。这时候就得靠系统推送(比如Android的FCM、iOS的APNs)来补位:后端发消息的时候,同时发Pusher消息和系统推送消息,这样不管APP是活着还是死了,用户都能收到通知。
具体操作步骤
1. 集成Firebase Cloud Messaging(FCM)(跨平台通用)
先给你的Flutter项目加上FCM,用来处理系统级推送:
- 先在
pubspec.yaml里加依赖:firebase_messaging: ^14.0.0(版本可以跟着官方最新的来) - 然后按Firebase的文档配置Android和iOS的环境:比如Android要下载
google-services.json放对位置,iOS要配置APNs证书,这些都是常规操作,跟着官方走就行。
2. 写FCM的初始化和消息监听代码
在APP启动的时候(比如main函数里)初始化FCM,处理各种场景的推送:
import 'package:firebase_messaging/firebase_messaging.dart'; Future<void> initFCM() async { FirebaseMessaging messaging = FirebaseMessaging.instance; // iOS必须要请求推送权限,Android可选 NotificationSettings settings = await messaging.requestPermission( alert: true, badge: true, sound: true, ); // 获取设备的FCM令牌,后端需要用这个令牌给特定设备发推送 String? token = await messaging.getToken(); print("当前设备FCM令牌: $token"); // 处理APP前台时收到的推送 FirebaseMessaging.onMessage.listen((RemoteMessage message) { print('收到推送: ${message.notification?.title}'); // 直接调用你现有的_showNotification方法显示本地通知就行 _showNotification(message.notification?.title, message.notification?.body); }); // 处理用户点击通知打开APP的场景(APP在后台时) FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { print('用户点了推送!'); // 这里可以跳转到对应的页面,比如邮件详情页 }); // 处理APP彻底关闭时,用户点击推送启动APP的场景 RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) { // 启动APP后直接处理这条消息,比如跳转到对应的页面 } }
3. 后端配合发双渠道消息
你的后端服务在要发通知的时候,得同时干两件事:
- 继续发Pusher消息,保证APP在前台/后台时能实时收到
- 用刚才拿到的FCM令牌发FCM推送消息,保证APP被杀死时系统能弹出通知
4. 优化你现有的Pusher代码
另外,你现在在Pusher绑定事件里每次都初始化本地通知,这没必要,初始化只需要做一次就行,把这段代码移到APP启动时:
// 把本地通知初始化移到main函数或者APP初始化的地方 Future<void> initLocalNotifications() async { var initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); var initializationSettingsIOS = IOSInitializationSettings(); var initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsIOS, ); await flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: onSelectNotification); } // 然后在Pusher的bind事件里只处理消息和显示通知 channel.bind(eventName,(last){ final String data = last.data; print("邮件消息数据: $data"); _inEventData.add(data); _showNotification(); });
替代方案:用Pusher Beams
要是不想折腾FCM,也可以试试Pusher官方的Pusher Beams(之前叫Pusher Push Notifications),这玩意专门处理跨平台推送,集成之后直接通过Pusher后台就能发推送,不用单独对接FCM/APNs。你可以把现在的pusher_websocket_flutter换成pusher_beams包,它同时支持实时消息和推送通知,一步到位。
内容的提问来源于stack exchange,提问作者Aarti
相关产品推荐
相关产品推荐

