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

Flutter推送通知:如何禁用FCM自动通知或捕获后台数据消息?

解决方案

需求1:阻止FCM自动创建通知,统一用flutter_local_notifications展示

Android 端配置

  1. 自定义FirebaseMessagingService拦截通知,避免系统自动展示:
    在android/app/src/main/kotlin/[你的包名]/下创建CustomMessagingService.kt:
    import com.google.firebase.messaging.FirebaseMessagingService
    import com.google.firebase.messaging.RemoteMessage
    import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService
    
    class CustomMessagingService : FirebaseMessagingService() {
        override fun onMessageReceived(remoteMessage: RemoteMessage) {
            // 将消息转发给Flutter端处理
            FlutterFirebaseMessagingService.handleMessage(this, remoteMessage)
            // 不调用父类方法,阻止系统自动生成通知
        }
    }
    
  2. 修改AndroidManifest.xml,替换默认服务:
    在application标签内添加:
    <service
        android:name=".CustomMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    
    移除原有默认的FirebaseMessagingService注册项。

iOS 端配置

修改AppDelegate.swift,设置通知代理拦截系统展示:

import UIKit
import Flutter
import Firebase
import UserNotifications

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, UNUserNotificationCenterDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        FirebaseApp.configure()
        
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: { _, _ in }
        )
        application.registerForRemoteNotifications()
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    // 拦截通知展示
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([]) // 告诉系统不自动展示
        if let message = notification.request.content.userInfo as? [String: Any] {
            FirebaseMessaging.instance.app.send(message) // 转发给Flutter
        }
    }
    
    // 处理通知点击
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        if let message = response.notification.request.content.userInfo as? [String: Any] {
            FirebaseMessaging.instance.app.send(message)
        }
        completionHandler()
    }
}

Flutter 端统一处理

监听所有消息回调,用flutter_local_notifications展示:

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;

void setupNotifications() async {
  // 初始化本地通知插件
  const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
  const DarwinInitializationSettings iosSettings = DarwinInitializationSettings();
  const InitializationSettings settings = InitializationSettings(android: androidSettings, iOS: iosSettings);
  await _notificationsPlugin.initialize(settings);

  // 前台消息监听
  FirebaseMessaging.onMessage.listen(showCustomNotification);
  // 后台/终止状态消息监听
  FirebaseMessaging.onBackgroundMessage(_handleBackgroundMessage);
}

void showCustomNotification(RemoteMessage message) async {
  String title = message.notification?.title ?? '新通知';
  String body = message.notification?.body ?? '您有一条新消息';
  String? customData = message.data['custom_key'];

  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'custom_notification_channel',
    '自定义通知',
    importance: Importance.high,
    priority: Priority.high,
  );
  const DarwinNotificationDetails iosDetails = DarwinNotificationDetails();
  const NotificationDetails details = NotificationDetails(android: androidDetails, iOS: iosDetails);

  await _notificationsPlugin.show(
    DateTime.now().millisecondsSinceEpoch,
    title,
    body,
    details,
    payload: customData,
  );
}

// 后台消息处理(必须为顶级函数)
Future<void> _handleBackgroundMessage(RemoteMessage message) async {
  // 重新初始化本地通知插件
  const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
  const DarwinInitializationSettings iosSettings = DarwinInitializationSettings();
  const InitializationSettings settings = InitializationSettings(android: androidSettings, iOS: iosSettings);
  final FlutterLocalNotificationsPlugin notificationsPlugin = FlutterLocalNotificationsPlugin();
  await notificationsPlugin.initialize(settings);

  String title = message.notification?.title ?? '新通知';
  String body = message.notification?.body ?? '您有一条新消息';

  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'custom_notification_channel',
    '自定义通知',
    importance: Importance.high,
    priority: Priority.high,
  );
  const DarwinNotificationDetails iosDetails = DarwinNotificationDetails();
  const NotificationDetails details = NotificationDetails(android: androidDetails, iOS: iosDetails);

  await notificationsPlugin.show(
    DateTime.now().millisecondsSinceEpoch,
    title,
    body,
    details,
  );
}

需求2:后台/终止状态捕获仅数据消息并展示

前提配置

  1. Android:完成需求1中的自定义FirebaseMessagingService配置。
  2. iOS:在Xcode项目设置的Signing & Capabilities中,勾选Background Modes下的Remote notifications。

Flutter 端处理

复用需求1中的Flutter代码,核心是onBackgroundMessage回调——它会在应用终止或后台时触发数据消息的处理。

服务器数据消息格式

确保发送纯数据消息,示例结构:

{
  "message": {
    "token": "token_1",
    "data": {
      "title": "自定义标题",
      "body": "自定义内容",
      "custom_key": "自定义扩展数据"
    }
  }
}

Flutter端可从message.data中提取字段,用flutter_local_notifications展示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:38:18