Flutter iOS端App终止状态下点击FCM通知无法启动问题排查
iOS平台FCM通知点击无法启动终止状态App的解决方案
问题分析
App处于前台/后台时点击通知可正常启动,但终止状态下仅能收到通知,点击后无法启动App。核心原因是iOS端未正确处理终止状态下的通知点击事件,导致FCM无法将初始消息传递到Flutter侧,同时导航逻辑存在框架适配问题。
解决方案
1. 修改iOS端AppDelegate.swift
添加通知中心代理实现,确保通知点击事件被FCM捕获:
import UIKit import Flutter import GoogleMaps import Firebase import FirebaseAuth import FirebaseMessaging import UserNotifications @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate, UNUserNotificationCenterDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GMSServices.provideAPIKey("ANY API KEY") // 初始化Firebase FirebaseApp.configure() // 设置通知中心代理,处理通知交互 UNUserNotificationCenter.current().delegate = self // 请求通知权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in if granted { DispatchQueue.main.async { application.registerForRemoteNotifications() } } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { Auth.auth().setAPNSToken(deviceToken, type: .prod) Messaging.messaging().apnsToken = deviceToken super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) } // 前台收到通知时的展示配置 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .badge, .sound]) } // 处理通知点击(包括App终止状态) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // 将通知数据传递给FCM,确保Flutter侧能获取初始消息 Messaging.messaging().appDidReceiveMessage(response.notification.request.content.userInfo) completionHandler() } // 后台接收通知的处理 override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { Messaging.messaging().appDidReceiveMessage(userInfo) completionHandler(.newData) } }
2. 调整Flutter侧Main.dart的导航逻辑
由于使用了GetMaterialApp,需改用GetX导航方法替代原生Navigator,避免上下文初始化问题:
class _MyAppState extends State<MyApp> { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) async { if (widget.message != null) { // 延迟等待GetX框架初始化完成 await Future.delayed(const Duration(milliseconds: 1000)); // 根据消息类型处理跳转逻辑 if (widget.message!.data['type'].toString() == 'order') { var order = await orderCollection.doc('zTuAXK4goqIErVHPqPIZQqkAKJKs').get(); OrderModel newOrder = OrderModel.fromJson(order.data()!); Get.to(() => OrderDetailsScreen(order: newOrder)); } else { // 默认跳转首页 Get.offAll(() => const HomeScreen()); } } }); } // ... 其他代码不变 }
3. 配置iOS Info.plist
添加后台通知权限及FCM代理配置:
<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array> <key>FirebaseAppDelegateProxyEnabled</key> <false/>
关键说明
- iOS终止状态下点击通知,会触发
userNotificationCenter:didReceiveNotificationResponse:方法,必须在此将通知数据传递给FCM,才能让Flutter侧的getInitialMessage获取到消息。 - 使用GetX框架时,必须用GetX的导航API,否则会因上下文未初始化导致跳转失败。
- 确保
FirebaseApp.configure()在App启动时被调用,这是FCM正常工作的前提。
内容的提问来源于stack exchange,提问作者Arjun Mahar
相关产品推荐
相关产品推荐

