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

Flutter iOS端Firebase onMessage在APNS推送时未触发问题

问题解答

firebase_messaging的onMessage回调仅针对通过Firebase Cloud Messaging(FCM)发送的消息生效,直接通过APNS推送的消息不会触发该回调。但你可以通过「原生iOS代码+Flutter MethodChannel通信」的方式,实现iOS端APNS推送的监听和自定义控制,达到和Android端一致的逻辑效果。

具体实现步骤:

1. 调整APNS推送Payload格式

根据你的需求(先接收数据再决定是否展示),推送Payload需要满足:

  • 若要在App前台捕获消息:
    • 带UI的通知:保留aps.alert等字段,但需通过原生回调拦截处理;
    • 静默通知:必须包含content-available: 1,且不能包含alert、sound等UI相关字段,App会在后台/前台唤醒处理。
  • 自定义数据可放在aps字段外,或aps内的custom字段中,确保能被原生代码读取。

2. iOS原生代码添加通知监听

在AppDelegate.swift中实现UNUserNotificationCenterDelegate的回调,将APNS消息传递给Flutter:

import UIKit
import Flutter
import FirebaseMessaging

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    
    // 配置通知权限与代理
    UNUserNotificationCenter.current().delegate = self
    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }
    application.registerForRemoteNotifications()
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
  
  // App前台收到通知时触发,拦截并传递消息给Flutter
  override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let userInfo = notification.request.content.userInfo
    let channel = FlutterMethodChannel(name: "com.your.app/notification", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger)
    channel.invokeMethod("onAPNSForegroundMessage", arguments: userInfo)
    
    // 自定义控制是否展示通知:比如根据userInfo判断后调用completionHandler
    // 不展示:completionHandler([])
    // 展示默认样式:completionHandler([.alert, .sound, .badge])
  }
  
  // 用户点击通知时触发
  override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    let channel = FlutterMethodChannel(name: "com.your.app/notification", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger)
    channel.invokeMethod("onAPNSNotificationTap", arguments: userInfo)
    completionHandler()
  }
}

3. Flutter侧接收原生传递的消息

创建MethodChannel监听原生发来的APNS消息,实现自定义逻辑:

import 'package:flutter/services.dart';

class APNSNotificationHandler {
  static const _notificationChannel = MethodChannel('com.your.app/notification');

  static void init() {
    _notificationChannel.setMethodCallHandler((call) async {
      switch (call.method) {
        case 'onAPNSForegroundMessage':
          final Map<String, dynamic> message = Map<String, dynamic>.from(call.arguments);
          // 这里实现你的自定义逻辑:判断是否展示通知、保存数据等
          print('Received APNS foreground message: $message');
          break;
        case 'onAPNSNotificationTap':
          final Map<String, dynamic> message = Map<String, dynamic>.from(call.arguments);
          // 处理用户点击通知的逻辑
          print('APNS notification tapped: $message');
          break;
      }
    });
  }
}

在main.dart的initState中初始化监听:

@override
void initState() {
  super.initState();
  APNSNotificationHandler.init();
  // 保留原有的FCM监听
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    // FCM消息处理逻辑
  });
}

4. 关键注意事项

  • 确保iOS App开启了「后台刷新」权限(在Xcode的Signing & Capabilities中添加Background Modes,勾选Remote notifications);
  • 静默通知的Payload必须严格符合Apple要求:content-available: 1,无UI字段,且推送时需开启“优先级高”;
  • 若需要修改通知内容,Payload需添加mutable-content: 1,并在原生代码中处理通知扩展。

内容的提问来源于stack exchange,提问作者Lea González Cuello

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:04:54