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

求助:Flutter基于firebase_messaging实现自定义FCM推送通知(Android/iOS)

我刚搞定这个需求没多久,给你一步步讲怎么在Flutter里实现自定义FCM通知——涵盖你要的自定义音效、标题、大文本和图标。核心是要同时处理前台和后台两种场景,还要配合Firebase的消息payload来传递自定义参数,具体步骤如下:

1. 准备依赖和Android资源

首先在pubspec.yaml里添加必要的包:

dependencies:
  firebase_core: ^2.15.0 # 替换成最新版本
  firebase_messaging: ^14.6.5 # 替换成最新版本
  flutter_local_notifications: ^16.1.0 # 替换成最新版本

然后处理Android端的资源:

  • 把自定义音效文件(比如custom_sound.mp3)放到android/app/src/main/res/raw目录(没有raw文件夹就新建一个);
  • 把自定义通知图标(透明背景的PNG)放到android/app/src/main/res/mipmap-xxxhdpi等对应分辨率的目录,确保图标文件名全小写、无特殊字符。

2. 初始化通知服务

在main.dart的main函数里,先初始化Firebase和本地通知插件:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化Firebase
  await Firebase.initializeApp();
  
  // 初始化flutter_local_notifications,指定默认的自定义图标
  const AndroidInitializationSettings androidInitSettings =
      AndroidInitializationSettings('@mipmap/custom_notification_icon');
  const InitializationSettings initSettings =
      InitializationSettings(android: androidInitSettings);
  await FlutterLocalNotificationsPlugin().initialize(initSettings);
  
  // 注册后台消息处理器
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  
  runApp(const MyApp());
}

3. 处理前台消息(App在前台运行时)

当App在前台时,FCM的消息会触发onMessage回调,我们在这里用flutter_local_notifications构建完全自定义的通知:

// 在你的Widget初始化或者main函数后监听
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  // 从消息的data字段提取自定义参数(建议把所有自定义内容放data里)
  final customTitle = message.data['custom_title'] ?? message.notification?.title ?? '默认标题';
  final customBigText = message.data['custom_big_text'] ?? message.notification?.body ?? '默认内容';
  final customSound = message.data['custom_sound'] ?? 'custom_sound';

  // 构建Android通知详情,设置自定义音效、大文本样式
  final AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'custom_notification_channel', // 唯一的渠道ID
    '自定义通知渠道', // 渠道名称,用户在系统设置里能看到
    channelDescription: '用于展示自定义样式的FCM通知',
    importance: Importance.max,
    priority: Priority.high,
    sound: RawResourceAndroidNotificationSound(customSound),
    // 大文本样式
    styleInformation: BigTextStyleInformation(customBigText),
  );

  const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);

  // 显示通知
  FlutterLocalNotificationsPlugin().show(
    DateTime.now().millisecondsSinceEpoch ~/ 1000, // 唯一通知ID
    customTitle,
    customBigText,
    notificationDetails,
  );
});

4. 处理后台/杀死状态下的消息

当App在后台或者被杀死时,需要用后台消息处理器来处理,注意这个处理器是在隔离线程运行,所以要重新初始化必要的服务:

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // 必须重新初始化Firebase
  await Firebase.initializeApp();
  
  // 初始化本地通知插件
  const AndroidInitializationSettings androidInitSettings =
      AndroidInitializationSettings('@mipmap/custom_notification_icon');
  const InitializationSettings initSettings =
      InitializationSettings(android: androidInitSettings);
  await FlutterLocalNotificationsPlugin().initialize(initSettings);

  // 提取自定义参数
  final customTitle = message.data['custom_title'] ?? '后台通知';
  final customBigText = message.data['custom_big_text'] ?? '后台通知内容';
  final customSound = message.data['custom_sound'] ?? 'custom_sound';

  // 构建通知详情
  final AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'custom_notification_channel',
    '自定义通知渠道',
    channelDescription: '用于展示自定义样式的FCM通知',
    importance: Importance.max,
    priority: Priority.high,
    sound: RawResourceAndroidNotificationSound(customSound),
    styleInformation: BigTextStyleInformation(customBigText),
  );

  const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);

  // 显示通知
  await FlutterLocalNotificationsPlugin().show(
    DateTime.now().millisecondsSinceEpoch ~/ 1000,
    customTitle,
    customBigText,
    notificationDetails,
  );
}

5. 发送自定义消息的Payload配置

不管是用Firebase控制台测试还是服务器端发送,都要把自定义参数放在Data字段里(不要用默认的Notification字段,否则后台时系统会自动弹默认通知):

  • 在Firebase控制台的「测试消息」里,点击「添加自定义数据」,添加:
    • custom_title: 你的自定义标题内容
    • custom_big_text: 你的大文本内容
    • custom_sound: 你的音效文件名(比如custom_sound,不需要加后缀)
  • 如果是服务器端发送HTTP请求,Payload示例:
{
  "to": "你的设备Token",
  "data": {
    "custom_title": "我的自定义标题",
    "custom_big_text": "这是一段很长的大文本内容,用来测试通知的大文本样式",
    "custom_sound": "custom_sound"
  }
}

几个关键注意事项

  • Android 8.0+必须创建通知渠道,flutter_local_notifications会自动帮你创建,但渠道的参数(比如重要性)要提前配置好;
  • 自定义音效必须是Android支持的格式(MP3、WAV等),文件名不能有大写、空格或特殊字符;
  • 自定义图标必须是透明背景的PNG,否则系统会替换成应用的默认图标;
  • 后台消息处理器里必须重新初始化Firebase和本地通知插件,因为它运行在独立的隔离线程中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:57:59