Flutter集成Cloud Functions与FCM时后台通知失效问题
Flutter Firebase通知收发异常排查与解决
问题概述
开发集成Firebase Firestore、Cloud Functions和Messaging的Flutter应用,实现通知收发功能,但存在部分场景通知失效:
通知正常工作场景
- 应用前台时,通过Cloud Function监听的集合创建新文档触发通知
- 应用前台时,通过Firebase控制台网页端发送通知
- 应用后台(未终止)时,通过Firebase控制台网页端发送通知
通知失效场景
- 应用后台时,通过Cloud Function监听的集合创建新文档触发通知
- 应用终止后,无论通过控制台还是Cloud Function发送的通知均无法接收
相关配置代码
Cloud Functions代码
import { messaging } from "firebase-admin"; import * as functions from "firebase-functions"; const { initializeApp } = require('firebase-admin/app'); initializeApp(); const token = "<my-token>"; exports.pushNotifications = functions .region('europe-central2') .firestore.document("signals/{docId}").onCreate( (snapshot) => { return messaging().send( { token: token, data: { title: "A New Notification", body: "Hello world!", } } ); } );
Flutter前端代码
class Notifications { static final messagingInstance = FirebaseMessaging.instance; static final Stream<RemoteMessage> foregroundNotificationsStream = FirebaseMessaging.onMessage; static final StreamSubscription<RemoteMessage> notificationsListener = FirebaseMessaging.onMessage.listen((RemoteMessage message) { if (message.data.isNotEmpty) { String body = ''; try { final payload = message.data['body']; if (payload is String) body = payload; } catch (e) { body = ''; } // Show dialog } else if (message.notification != null && message.notification!.body != null) { // show dialog } }); static void getToken() async { await messagingInstance.requestPermission(); final fcmToken = await messagingInstance.getToken(); Get.put(User()).updateAppUser(tokenStatus: fcmToken); Database.updateDBUser(); } }
Android Manifest配置
<intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </activity> <meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" /> <meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
问题原因与解决方法
1. Cloud Function消息格式缺失notification字段
应用处于后台/终止状态时,Firebase Messaging需要notification字段触发系统通知栏展示,仅发送data字段的通知不会自动弹出。修改Cloud Functions消息结构:
return messaging().send({ token: token, notification: { title: "A New Notification", body: "Hello world!" }, data: { title: "A New Notification", body: "Hello world!" // 可添加自定义业务数据 } });
2. 未处理后台/终止状态的通知回调
Flutter中,后台和终止状态的通知需要单独监听处理,更新前端代码:
class Notifications { static final messagingInstance = FirebaseMessaging.instance; static void initNotifications() { // 前台通知监听(原有逻辑) FirebaseMessaging.onMessage.listen((RemoteMessage message) { // 原有弹窗逻辑 }); // 后台点击通知进入应用的监听 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { // 处理通知点击事件,如跳转指定页面 }); // 应用终止时点击通知进入应用的处理 FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) { if (message != null) { // 处理通知点击事件 } }); } static void getToken() async { await messagingInstance.requestPermission(); // Android 13+ 需单独请求通知权限 if (Platform.isAndroid) { await Permission.notification.request(); } final fcmToken = await messagingInstance.getToken(); Get.put(User()).updateAppUser(tokenStatus: fcmToken); Database.updateDBUser(); } }
3. Android Manifest配置补全
在<application>标签内添加Firebase Messaging服务声明:
<service android:name="io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
4. 确保FCM Token有效性
避免硬编码Token,建议将用户的FCM Token存储在Firestore中,触发通知时从数据库获取最新Token(Token会在应用卸载重装、设备系统更新时变化)。
内容的提问来源于stack exchange,提问作者Miro
相关产品推荐
相关产品推荐

