求助: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
相关产品推荐
相关产品推荐

