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

Flutter中Firebase通知Android正常iOS无响应问题求助

iOS无法接收Firebase通知的排查与修复

针对你的场景——Android设备正常接收通知但iOS无响应,结合代码细节与iOS FCM的特性,可从以下几个核心方向排查修复:

1. 补全iOS通知权限配置与请求

你当前的权限请求未指定具体权限项,iOS默认可能未授予alert/sound等关键权限(即使系统设置显示开启,也可能存在配置不匹配问题)。同时DarwinInitializationSettings需明确开启权限请求:

修改initNotification()中的权限请求逻辑:

await _firebaseMessaging.requestPermission(
  alert: true,
  badge: true,
  sound: true,
);

更新NotificationApi.init()中的iOS初始化配置:

static void init() {
  _notification.initialize(
    InitializationSettings(
      android: const AndroidInitializationSettings('@mipmap/ic_launcher'),
      iOS: DarwinInitializationSettings(
        requestAlertPermission: true,
        requestBadgePermission: true,
        requestSoundPermission: true,
      ),
    ),
  );
}

2. 修正FCM消息格式(后台/杀死状态关键)

iOS对FCM消息格式的要求远严格于Android:

  • 当App处于后台或被杀死状态,FCM消息必须包含notification字段(不能仅传data字段),否则APNs不会触发通知弹窗。
  • 若需发送纯data消息并触发后台处理,需在Firebase函数请求中添加content_available: true,但这类静默通知不会弹出弹窗,仅用于后台数据同步。

修改NotificationApi.pushNotification(),兼容notification与data两种字段格式:

static pushNotification(RemoteMessage message) async {
  final title = message.notification?.title ?? message.data['title'];
  final body = message.notification?.body ?? message.data['body'];
  if (title == null || body == null) return;

  var androidPlatformChannelSpecifics = const AndroidNotificationDetails(
    'channel_id', // 修正原拼写错误:channed id → 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(
    DateTime.now().millisecondsSinceEpoch, // 用唯一ID避免通知被覆盖
    title,
    body,
    platformChannelSpecifics,
  );
}

3. 调整后台消息处理逻辑(iOS环境限制)

iOS后台消息处理(onBackgroundMessage)有严格的资源限制,无法在该回调中触发本地通知弹窗(仅APNs直接推送的通知可在后台弹出)。建议简化后台逻辑:

Future<void> handleBackgroundMessage(RemoteMessage? message) async {
  if (message != null) {
    // 仅执行轻量后台操作,比如更新本地缓存、同步Firestore数据等
    // 移除本地通知调用,交由APNs处理弹窗逻辑
  }
}

4. 修正初始化顺序

本地通知插件应在Firebase通知初始化前完成初始化,调整main函数顺序:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  NotificationApi.init(); // 先初始化本地通知插件
  await DBHandler().initNotification();
  await FlutterConfig.loadEnvVariables();

  runApp(ProviderScope(
    child: MyApp(),
  ));
}

5. 验证FCM Token与APNs配置

  • 确认iOS设备的FCM Token已正确上传到Firestore:在generateDeviceToken()中打印token,检查是否获取到有效值,且与Firebase控制台中的设备记录一致。
  • 检查Firebase项目的APNs配置:确保上传了对应环境(开发/生产)的APNs证书,Bundle ID与Xcode配置完全匹配,且证书未过期。
  • 测试环境需对应:debug包用开发APNs证书,release包用生产证书,混用会导致通知无法送达。

6. 验证前台通知回调

iOS前台状态下不会自动弹出通知,需依赖onMessage回调触发本地通知。可添加日志确认回调是否正常触发:

FirebaseMessaging.onMessage.listen((event) async {
  print('Received foreground message: ${event.data}');
  await NotificationApi.pushNotification(event);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:57:50