6.8 C
Canberra
Wednesday, April 15, 2026

flutter – firebase_messaging onMessage stream by no means fires after UIScene migration on iOS


After migrating a Flutter iOS app to make use of UISceneDelegation (by way of FlutterSceneDelegate in Information.plist), FirebaseMessaging.onMessage in Dart by no means fires for foreground messages. Background banners seem appropriately by way of APNs, however the Dart layer receives nothing — no onMessage, no onMessageOpenedApp logs, and no getInitialMessage information.

What works:

  • FCM token is generated and non-null

  • Push notification banners seem when the app is backgrounded

  • didRegisterForRemoteNotificationsWithDeviceToken fires appropriately

  • UNUserNotificationCenter willPresent fires appropriately (confirmed by way of Swift print)

  • Messaging.messaging().appDidReceiveMessage(userInfo) is known as efficiently from willPresent

What breaks:

  • FirebaseMessaging.onMessage by no means fires in Dart

  • FirebaseMessaging.onMessageOpenedApp by no means fires in Dart

  • No Dart-side logs seem for any incoming notification

  • Root Trigger (Identified): When utilizing FlutterImplicitEngineDelegate, plugins are registered by way of: func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) }, After GeneratedPluginRegistrant.register runs, FLTFirebaseMessagingPlugin is predicted to set itself as Messaging.messaging().delegate. Nevertheless, printing the delegate instantly after registration reveals: print(Messaging.messaging().delegate) // → nil

This didn’t happen earlier than the UIScene migration, when GeneratedPluginRegistrant.register(with: self) was known as in didFinishLaunchingWithOptions and FlutterAppDelegate (which lives for the app’s lifetime) held the plugins strongly.

That is my appdelegate.swift file:

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

And that is my data.plist file:



    
    UIApplicationSceneManifest
     
      UIApplicationSupportsMultipleScenes
      
      UISceneConfigurations
      
      UIWindowSceneSessionRoleApplication
        
          
            UISceneClassName
            UIWindowScene
            UISceneDelegateClassName
            FlutterSceneDelegate
            UISceneConfigurationName
            flutter
            UISceneStoryboardFile
            Major
          
        
       
     
       CFBundleDevelopmentRegion
       $(DEVELOPMENT_LANGUAGE)
       CFBundleDisplayName
       Bongo Funds
       CFBundleExecutable
       $(EXECUTABLE_NAME)
       CFBundleIdentifier
       $(PRODUCT_BUNDLE_IDENTIFIER)
       CFBundleInfoDictionaryVersion
       6.0
       CFBundleName
       bongo_pay
       CFBundlePackageType
       APPL
       CFBundleShortVersionString
       $(FLUTTER_BUILD_NAME)
       CFBundleSignature
       ????
       UIBackgroundModes
       
          remote-notification
       
       FirebaseAppDelegateProxyEnabled
       
       NSAppTransportSecurity
       
          NSAllowsArbitraryLoads
          
       
       CFBundleVersion
       $(FLUTTER_BUILD_NUMBER)
       NSLocationWhenInUseUsageDescription
       We want your location to offer higher service.
       NSLocationAlwaysAndWhenInUseUsageDescription
       This app makes use of notifications
       NSLocationAlwaysUsageDescription
       We want your location even when the app is within the background.
       NSUserTrackingUsageDescription
       This app makes use of notifications
       LSRequiresIPhoneOS
       
       UILaunchStoryboardName
       LaunchScreen
       UIMainStoryboardFile
       Major
       NSFaceIDUsageDescription
       This app requires Face ID authentication to safe your private information and guarantee solely you'll be able to entry your account.
       NSCameraUsageDescription
       We want entry to your digital camera to take pictures.
       NSPhotoLibraryUsageDescription
       We want entry to your photograph library to add photographs.
       NSAppleMusicUsageDescription
        This app doesn't use Apple Music however requires restricted media library entry for system options.
       UISupportedInterfaceOrientations
       
          UIInterfaceOrientationPortrait
          UIInterfaceOrientationLandscapeLeft
          UIInterfaceOrientationLandscapeRight
       
       UISupportedInterfaceOrientations~ipad
       
          UIInterfaceOrientationPortrait
          UIInterfaceOrientationPortraitUpsideDown
          UIInterfaceOrientationLandscapeLeft
          UIInterfaceOrientationLandscapeRight
       
       CADisableMinimumFrameDurationOnPhone
       
       UIApplicationSupportsIndirectInputEvents
       
       io.flutter.embedded_views_preview
       
       NSMicrophoneUsageDescription
       We want entry to your microphone for video or audio seize in net pages.
       NSPhotoLibraryAddUsageDescription
       We want entry to save lots of photographs to your photograph library.
       UIFileSharingEnabled
       
       LSSupportsOpeningDocumentsInPlace
       
       UIStatusBarHidden
       
    

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

[td_block_social_counter facebook="tagdiv" twitter="tagdivofficial" youtube="tagdiv" style="style8 td-social-boxed td-social-font-icons" tdc_css="eyJhbGwiOnsibWFyZ2luLWJvdHRvbSI6IjM4IiwiZGlzcGxheSI6IiJ9LCJwb3J0cmFpdCI6eyJtYXJnaW4tYm90dG9tIjoiMzAiLCJkaXNwbGF5IjoiIn0sInBvcnRyYWl0X21heF93aWR0aCI6MTAxOCwicG9ydHJhaXRfbWluX3dpZHRoIjo3Njh9" custom_title="Stay Connected" block_template_id="td_block_template_8" f_header_font_family="712" f_header_font_transform="uppercase" f_header_font_weight="500" f_header_font_size="17" border_color="#dd3333"]
- Advertisement -spot_img

Latest Articles