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

Flutter iOS迁移UIScene后FirebaseMessaging.onMessage无法触发

Flutter iOS迁移UISceneDelegate后FirebaseMessaging.onMessage前台不触发问题

将Flutter iOS应用迁移为使用UISceneDelegation(通过Info.plist中的FlutterSceneDelegate)后,Dart层的FirebaseMessaging.onMessage在应用前台时完全无法触发。通过APNs发送的后台通知横幅显示正常,但Dart层接收不到任何消息——既没有onMessage、onMessageOpenedApp的日志,也没有getInitialMessage返回的数据。

正常工作项

  • FCM令牌生成成功且非空
  • 应用后台时推送通知横幅正常显示
  • didRegisterForRemoteNotificationsWithDeviceToken回调正常触发
  • UNUserNotificationCenter的willPresent回调正常触发(已通过Swift打印确认)
  • 从willPresent中成功调用Messaging.messaging().appDidReceiveMessage(userInfo)

失效项

  • Dart层的FirebaseMessaging.onMessage始终不触发
  • Dart层的FirebaseMessaging.onMessageOpenedApp始终不触发
  • 无任何通知相关的Dart端日志
  • 已定位根因:使用FlutterImplicitEngineDelegate时,插件通过func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) }注册。GeneratedPluginRegistrant.register执行后,预期FLTFirebaseMessagingPlugin会将自身设置为Messaging.messaging().delegate,但注册后立即打印该代理显示为nil。

迁移至UIScene之前无此问题,当时在didFinishLaunchingWithOptions中调用GeneratedPluginRegistrant.register(with: self),且FlutterAppDelegate(生命周期与应用一致)会强引用插件。

AppDelegate.swift代码

import Flutter
import Firebase
import UserNotifications
import flutter_local_notifications
@main
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    UNUserNotificationCenter.current().delegate = self
    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }
    application.registerForRemoteNotifications()
//     GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
  func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
  // This is required to make any communication available in the action isolate.
      FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
          GeneratedPluginRegistrant.register(with: registry)
      }
      GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
    }
  override func application(_ application: UIApplication,
                            didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    Messaging.messaging().apnsToken = deviceToken
//     print("✅ APNs token: \(deviceToken.map { String(format: "%02x", $0) }.joined())")
    super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
  }
//   override func application(_ application: UIApplication,
//                             didReceiveRemoteNotification userInfo: [AnyHashable : Any],
//                             fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
//     Messaging.messaging().appDidReceiveMessage(userInfo)
//     completionHandler(.newData)
//   }
}

Info.plist代码

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
    <key>UIApplicationSceneManifest</key>
     <dict>
      <key>UIApplicationSupportsMultipleScenes</key>
      <false/>
      <key>UISceneConfigurations</key>
      <dict>
      <key>UIWindowSceneSessionRoleApplication</key>
        <array>
          <dict>
            <key>UISceneClassName</key>
            <string>UIWindowScene</string>
            <key>UISceneDelegateClassName</key>
            <string>FlutterSceneDelegate</string>
            <key>UISceneConfigurationName</key>
            <string>flutter</string>
            <key>UISceneStoryboardFile</key>
            <string>Main</string>
          </dict>
        </array>
       </dict>
     </dict>
       <key>CFBundleDevelopmentRegion</key>
       <string>$(DEVELOPMENT_LANGUAGE)</string>
       <key>CFBundleDisplayName</key>
       <string>Bongo Payments</string>
       <key>CFBundleExecutable</key>
       <string>$(EXECUTABLE_NAME)</string>
       <key>CFBundleIdentifier</key>
       <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
       <key>CFBundleInfoDictionaryVersion</key>
       <string>6.0</string>
       <key>CFBundleName</key>
       <string>bongo_pay</string>
       <key>CFBundlePackageType</key>
       <string>APPL</string>
       <key>CFBundleShortVersionString</key>
       <string>$(FLUTTER_BUILD_NAME)</string>
       <key>CFBundleSignature</key>
       <string>????</string>
       <key>UIBackgroundModes</key>
       <array>
          <string>remote-notification</string>
       </array>
       <key>FirebaseAppDelegateProxyEnabled</key>
       <false/>
       <key>NSAppTransportSecurity</key>
       <dict>
          <key>NSAllowsArbitraryLoads</key>
          <true/>
       </dict>
       <key>CFBundleVersion</key>
       <string>$(FLUTTER_BUILD_NUMBER)</string>
       <key>NSLocationWhenInUseUsageDescription</key>
       <string>We need your location to provide better service.</string>
       <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
       <string>This app uses notifications</string>
       <key>NSLocationAlwaysUsageDescription</key>
       <string>We need your location even when the app is in the background.</string>
       <key>NSUserTrackingUsageDescription</key>
       <string>This app uses notifications</string>
       <key>LSRequiresIPhoneOS</key>
       <true/>
       <key>UILaunchStoryboardName</key>
       <string>LaunchScreen</string>
       <key>UIMainStoryboardFile</key>
       <string>Main</string>
       <key>NSFaceIDUsageDescription</key>
       <string>This app requires Face ID authentication to secure your personal data and ensure only you can access your account.</string>
       <key>NSCameraUsageDescription</key>
       <string>We need access to your camera to take photos.</string>
       <key>NSPhotoLibraryUsageDescription</key>
       <string>We need access to your photo library to upload images.</string>
       <key>NSAppleMusicUsageDescription</key>
        <string>This app does not use Apple Music but requires limited media library access for system features.</string>
       <key>UISupportedInterfaceOrientations</key>
       <array>
          <string>UIInterfaceOrientationPortrait</string>
          <string>UIInterfaceOrientationLandscapeLeft</string>
          <string>UIInterfaceOrientationLandscapeRight</string>
       </array>
       <key>UISupportedInterfaceOrientations~ipad</key>
       <array>
          <string>UIInterfaceOrientationPortrait</string>
          <string>UIInterfaceOrientationPortraitUpsideDown</string>
          <string>UIInterfaceOrientationLandscapeLeft</string>
          <string>UIInterfaceOrientationLandscapeRight</string>
       </array>
       <key>CADisableMinimumFrameDurationOnPhone</key>
       <true/>
       <key>UIApplicationSupportsIndirectInputEvents</key>
       <true/>
       <key>io.flutter.embedded_views_preview</key>
       <true/>
       <key>NSMicrophoneUsageDescription</key>
       <string>We need access to your microphone for video or audio capture in web pages.</string>
       <key>NSPhotoLibraryAddUsageDescription</key>
       <string>We need access to save images to your photo library.</string>
       <key>UIFileSharingEnabled</key>
       <true/>
       <key>LSSupportsOpeningDocumentsInPlace</key>
       <true/>
       <key>UIStatusBarHidden</key>
       <false/>
    </dict>
</plist>

内容的提问来源于stack exchange,提问作者Kelvin Ekene

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 14:29:53