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

Flutter集成FCM后,如何实现后台收消息且自定义通知而非自动显示?

Flutter FCM后台自定义通知实现方案

要实现后台接收FCM消息且完全自定义通知样式,核心是避开系统自动处理的通知消息,改用数据消息 + 本地通知插件来实现,以下是分步骤的具体操作:

第一步:后端发送「数据消息」而非「通知消息」

FCM消息分两种类型,只有数据消息不会被系统自动弹出通知,完全由App控制:

  • 通知消息:后台/锁屏时系统直接弹通知,无法拦截自定义
  • 数据消息:系统仅传递数据,App接收后自行处理

后端发送消息时,必须使用纯数据格式(不要带notification字段),示例JSON:

{
  "to": "目标设备的FCM Token",
  "data": {
    "title": "你的自定义标题",
    "content": "你的自定义内容",
    "extra_data": "需要传递的额外参数"
  }
}

第二步:Flutter端配置与逻辑实现

需要用到firebase_messaging(处理FCM消息接收)和flutter_local_notifications(自定义通知样式)两个包:

1. 初始化本地通知插件

先配置本地通知的基础设置,确保能自定义样式:

import 'package:flutter_local_notifications/flutter_local_notifications.dart';

final FlutterLocalNotificationsPlugin _localNotifPlugin = FlutterLocalNotificationsPlugin();

Future<void> initLocalNotifications() async {
  // Android初始化:指定通知图标(用你自己的图标资源)
  const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher');
  // iOS初始化
  const iosInit = DarwinInitializationSettings();
  const initSettings = InitializationSettings(android: androidInit, iOS: iosInit);
  
  await _localNotifPlugin.initialize(initSettings);
  
  // Android 8.0+必须创建通知渠道
  await _createAndroidNotificationChannel();
}

// 创建自定义通知渠道(Android专属)
Future<void> _createAndroidNotificationChannel() async {
  const channel = AndroidNotificationChannel(
    'fcm_custom_channel', // 唯一渠道ID
    'FCM自定义通知', // 渠道名称
    description: '用于显示自定义样式的FCM通知',
    importance: Importance.high, // 通知重要性
  );
  
  await _localNotifPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);
}

2. 设置FCM后台消息处理器

后台消息的处理函数必须是顶级函数或静态函数(因为Flutter后台隔离环境无法访问类实例),在这里实现自定义通知的显示逻辑:

import 'package:firebase_messaging/firebase_messaging.dart';

// 后台消息处理回调(顶级函数)
Future<void> fcmBackgroundMessageHandler(RemoteMessage message) async {
  // 仅处理数据消息
  if (message.data.isEmpty) return;
  
  // 从数据中提取自定义内容
  final title = message.data['title'] ?? '默认标题';
  final content = message.data['content'] ?? '默认内容';
  final extra = message.data['extra_data'];
  
  // 构建自定义通知样式
  const androidDetails = AndroidNotificationDetails(
    'fcm_custom_channel', // 和之前创建的渠道ID一致
    'FCM自定义通知',
    importance: Importance.high,
    priority: Priority.high,
    // 可以添加更多自定义属性:大图标、小图标、进度条、样式模板等
  );
  const iosDetails = DarwinNotificationDetails();
  const notifDetails = NotificationDetails(android: androidDetails, iOS: iosDetails);
  
  // 显示自定义通知
  await _localNotifPlugin.show(
    DateTime.now().millisecondsSinceEpoch, // 唯一通知ID(避免重复)
    title,
    content,
    notifDetails,
    payload: extra, // 点击通知时传递的参数
  );
}

// 初始化FCM
Future<void> initFCM() async {
  final messaging = FirebaseMessaging.instance;
  
  // 请求iOS通知权限(Android默认开启,iOS必须主动请求)
  await messaging.requestPermission(
    alert: true,
    badge: true,
    sound: true,
  );
  
  // 设置后台消息处理器
  FirebaseMessaging.onBackgroundMessage(fcmBackgroundMessageHandler);
  
  // 可选:前台消息监听(App在前台时也用自定义通知)
  FirebaseMessaging.onMessage.listen((message) {
    if (message.data.isNotEmpty) {
      // 复用后台的通知显示逻辑即可
    }
  });
}

第三步:平台专属配置

Android端配置

  • 无需修改AndroidManifest.xml中的FCM服务配置,数据消息不会触发系统默认通知
  • 确保通知图标资源存在(@mipmap/ic_launcher对应你自己的应用图标)

iOS端配置

  1. 在Info.plist中添加以下配置,禁止FCM代理自动处理通知:
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
  1. 在Xcode中开启后台模式:选择你的项目 -> Signing & Capabilities -> 添加Background Modes -> 勾选「Remote notifications」
  2. 注意:iOS后台消息的送达受系统严格限制,App被完全杀死后可能无法及时接收,这是iOS系统机制,无法绕过

关键注意事项

  • 绝对不能发送带notification字段的混合消息,否则系统仍会自动弹出默认通知
  • 后台消息处理器必须是顶级/静态函数,不能是类的成员方法
  • 测试时,确保设备处于后台/锁屏状态,验证自定义通知是否正常显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:05:09