FCM消息已接收但通知不显示,背景消息处理遇空值错误
问题原因与解决方案
错误根源
报错Null check operator used on a null value是因为后台接收的FCM消息属于「数据消息(Data-only Message)」,此时RemoteMessage的notification字段为null,但你在NotificationApi.pushNotification中使用了强制非空运算符!直接访问message.notification!.title和message.notification!.body,触发了空指针异常。
从你的handleBackgroundMessage代码能看到,你已经在从message.data中读取title和body,却依然将完整message传给pushNotification,而该方法仅依赖message.notification字段,逻辑上存在矛盾。
修复方案
你需要修改NotificationApi的逻辑,使其适配「数据消息」的格式,避免强制访问可能为null的notification对象。
方案1:兼容两种消息格式
修改NotificationApi的pushNotification方法,同时支持从notification和data字段读取内容,再加默认值兜底:
static pushNotification(RemoteMessage message) async { var androidPlatformChannelSpecifics = const AndroidNotificationDetails( 'channel id', // 修正原拼写错误:channed → channel 'channel name', channelDescription: 'channel description', importance: Importance.max, priority: Priority.high, ); var iOSPlatformChannelSpecifics = const DarwinNotificationDetails(); var platformChannelSpecifics = NotificationDetails( android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics, ); // 优先取notification字段,无则从data取,最后用默认值兜底 final title = message.notification?.title ?? message.data['title'] ?? '新预订通知'; final body = message.notification?.body ?? message.data['body'] ?? '您有一条新的预订记录'; await _notification.show(0, title, body, platformChannelSpecifics); }
方案2:直接传入data中的内容(贴合现有逻辑)
- 修改
NotificationApi的pushNotification方法,直接接收标题和内容参数:
static pushNotification(String title, String body) async { var androidPlatformChannelSpecifics = const AndroidNotificationDetails( 'channel id', 'channel name', channelDescription: 'channel description', importance: Importance.max, priority: Priority.high, ); var iOSPlatformChannelSpecifics = const DarwinNotificationDetails(); var platformChannelSpecifics = NotificationDetails( android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics, ); await _notification.show(0, title, body, platformChannelSpecifics); }
- 在
handleBackgroundMessage中调用修改后的方法:
Future<void> handleBackgroundMessage(RemoteMessage message) async { final title = message.data['title'] ?? '新预订通知'; final body = message.data['body'] ?? '您有一条新的预订记录'; await NotificationApi.pushNotification(title, body); print('Title: $title'); print('Body: $body'); print('Payload: ${message.data}'); }
额外注意点
- 原代码中
AndroidNotificationDetails的channel id存在拼写错误(channed id),建议修正,避免Android端通知渠道创建异常。
内容的提问来源于stack exchange,提问作者Milan Labus
相关产品推荐
相关产品推荐

