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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 09:21:35