Is there an existing issue for this?
Which plugins are affected?
Messaging
Which platforms are affected?
iOS
Description
Since 16.5.0, apps that initialize Firebase from Dart (Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform), no GoogleService-Info.plist, no native FirebaseApp.configure()) never register for remote notifications at launch. As a result:
FirebaseMessaging.instance.getAPNSToken() stays null indefinitely on every launch (polled at 0 / 3 / 10 / 30 s).
getToken() throws [firebase_messaging/apns-token-not-set].
onTokenRefresh never fires.
- The only remaining path that calls
registerForRemoteNotifications is a permission request (e.g. via permission_handler), which is asynchronous, so the first getToken() right after the user grants permission races the APNs round-trip and loses most of the time. A device that already granted permission never registers again on relaunch.
The same app works on 16.4.3 (identical setup, only the plugin version differs).
Root cause
#18452 (shipped in 16.5.0) changed the launch-time registration in setupNotificationHandlingWithRemoteNotification: from an unconditional call to:
if ([FIRMessaging messaging].isAutoInitEnabled) {
[self registerForRemoteNotifications];
}
When Firebase is initialized from Dart, this runs before FirebaseApp.configure() has happened. +[FIRMessaging messaging] calls [FIRApp defaultApp], which logs I-COR000003 The default Firebase app has not yet been configured and returns nil, so FIR_COMPONENT(FIRMessagingInterop, nil.container) is nil and nil.isAutoInitEnabled evaluates to NO. Registration is skipped on every launch, and nothing re-runs it once Firebase is configured (didReinitializeFirebaseCore: in the messaging plugin is a no-op).
Dart-side initialization is a configuration this plugin explicitly supported before: #7754 was fixed by #7610 ("Set APNS token if user initializes Firebase app from Flutter"), which is why 16.4.3 works.
Why #18620 does not fix it
#18620 runs setupNotificationHandlingWithRemoteNotification: immediately at plugin registration when a scene is already connected. That fixes the missed-callback ordering, but the isAutoInitEnabled gate above is still evaluated before Firebase is configured. I applied the #18620 diff on top of 16.5.0 (local path override) and added an NSLog right before the gate:
[18620-PROBE] scene already connected at plugin registration, running setup now
[18620-PROBE] setup: FIRMessaging=nil isAutoInitEnabled=0
[TOKEN-PROBE] apns token not set within 30s
Setup ran, the gate was NO, and no APNs token arrived within 30 s.
Workaround
Calling FirebaseMessaging.instance.setAutoInitEnabled(true) on iOS right after Firebase.initializeApp(). messagingSetAutoInitEnabled: calls registerForRemoteNotifications and ensureAPNSTokenSetting unconditionally when enabled == YES. With that, the APNs token arrives ~0.8 s after launch, before the user reaches the permission prompt.
Suggested fix
Re-evaluate the auto-init gate once Firebase core is actually configured, for example in didReinitializeFirebaseCore: (call registerForRemoteNotifications there when [FIRMessaging messaging].isAutoInitEnabled is YES), or resolve the auto-init flag without requiring a FIRApp instance (Info.plist FirebaseMessagingAutoInitEnabled / the persisted user default). Either restores the 16.4.3 behaviour for Dart-initialized apps while keeping the opt-in semantics #18452 intended.
Reproducing the issue
- Take any Flutter app that initializes Firebase from Dart:
firebase_options.dart generated by flutterfire configure, Firebase.initializeApp(options: ...) in main(), no GoogleService-Info.plist in the iOS project, no native FirebaseApp.configure(). Method swizzling enabled (default). FirebaseMessagingAutoInitEnabled not set (defaults to enabled).
firebase_messaging: 16.5.0 (also reproduces on 16.6.0 and main).
- After
Firebase.initializeApp(), poll FirebaseMessaging.instance.getAPNSToken() every second for 30 s.
- Observe
null for the whole period, and getToken() throwing apns-token-not-set. Watch the unified log for the I-COR000003 lines emitted at plugin setup.
- Pin
firebase_messaging: 16.4.3 (and the matching firebase_core 4.12.1 so the Firebase iOS SDK pins agree): the APNs token arrives within ~1 s of launch.
Reproduces on an Apple silicon simulator (iPhone 17, iOS 26.5, which supports APNs) and on physical devices. UIScene vs. non-UIScene does not matter for this case.
Firebase Core version
4.13.0 (firebase_core_platform_interface 8.1.0, Firebase iOS SDK 12.17.0)
Flutter Version
3.44.9 (Dart 3.12.2), Xcode 26.6
Relevant Log Output
# at plugin setup (before Dart-side Firebase.initializeApp() completes)
[FirebaseCore][I-COR000012] Could not locate configuration file: 'GoogleService-Info.plist'.
[FirebaseCore][I-COR000003] The default Firebase app has not yet been configured. Add `FirebaseApp.configure()` to your application initialization. ...
[FirebaseCore][I-COR000003] The default Firebase app has not yet been configured. ...
# ~0.7 s later, Dart-side initialization completes
[FirebaseMessaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. ...
# Dart-side probe, same launch
[TOKEN-PROBE] probe t=0s apns=null
[TOKEN-PROBE] probe t=3s apns=null
[TOKEN-PROBE] probe t=10s apns=null
[TOKEN-PROBE] probe t=30s apns=null
# getToken() right after the user grants permission (permission_handler)
[TOKEN-PROBE] update() start apns=null
[TOKEN-PROBE] update() getToken threw apns-token-not-set: APNS token has not been received on the device yet. Please ensure the APNS token is available before calling `getAPNSToken()`.
Flutter dependencies
Expand Flutter dependencies snippet
firebase_core: ^4.6.0 # resolved 4.13.0
firebase_messaging: ^16.5.0 # resolved 16.5.0
firebase_analytics: ^12.4.6
firebase_crashlytics: ^5.2.7
firebase_remote_config: ^6.5.6
permission_handler: ^13.0.0 # used for the notification permission prompt
Additional context and comments
+[FIRMessaging messaging] returning nil before configure: FIRMessaging.m → [FIRApp defaultApp] → FIR_COMPONENT(FIRMessagingInterop, defaultApp.container); +[FIRApp defaultApp] logs I-COR000003 and returns nil when sDefaultApp is unset.
- The 16.5.0 → 16.6.0 iOS plugin diff only touches the macOS launch payload handling, so 16.6.0 is affected as well.
- Happy to test a patch on this setup.
Is there an existing issue for this?
Which plugins are affected?
Messaging
Which platforms are affected?
iOS
Description
Since 16.5.0, apps that initialize Firebase from Dart (
Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform), noGoogleService-Info.plist, no nativeFirebaseApp.configure()) never register for remote notifications at launch. As a result:FirebaseMessaging.instance.getAPNSToken()staysnullindefinitely on every launch (polled at 0 / 3 / 10 / 30 s).getToken()throws[firebase_messaging/apns-token-not-set].onTokenRefreshnever fires.registerForRemoteNotificationsis a permission request (e.g. viapermission_handler), which is asynchronous, so the firstgetToken()right after the user grants permission races the APNs round-trip and loses most of the time. A device that already granted permission never registers again on relaunch.The same app works on 16.4.3 (identical setup, only the plugin version differs).
Root cause
#18452 (shipped in 16.5.0) changed the launch-time registration in
setupNotificationHandlingWithRemoteNotification:from an unconditional call to:When Firebase is initialized from Dart, this runs before
FirebaseApp.configure()has happened.+[FIRMessaging messaging]calls[FIRApp defaultApp], which logsI-COR000003 The default Firebase app has not yet been configuredand returnsnil, soFIR_COMPONENT(FIRMessagingInterop, nil.container)isnilandnil.isAutoInitEnabledevaluates toNO. Registration is skipped on every launch, and nothing re-runs it once Firebase is configured (didReinitializeFirebaseCore:in the messaging plugin is a no-op).Dart-side initialization is a configuration this plugin explicitly supported before: #7754 was fixed by #7610 ("Set APNS token if user initializes Firebase app from Flutter"), which is why 16.4.3 works.
Why #18620 does not fix it
#18620 runs
setupNotificationHandlingWithRemoteNotification:immediately at plugin registration when a scene is already connected. That fixes the missed-callback ordering, but theisAutoInitEnabledgate above is still evaluated before Firebase is configured. I applied the #18620 diff on top of 16.5.0 (local path override) and added anNSLogright before the gate:Setup ran, the gate was
NO, and no APNs token arrived within 30 s.Workaround
Calling
FirebaseMessaging.instance.setAutoInitEnabled(true)on iOS right afterFirebase.initializeApp().messagingSetAutoInitEnabled:callsregisterForRemoteNotificationsandensureAPNSTokenSettingunconditionally whenenabled == YES. With that, the APNs token arrives ~0.8 s after launch, before the user reaches the permission prompt.Suggested fix
Re-evaluate the auto-init gate once Firebase core is actually configured, for example in
didReinitializeFirebaseCore:(callregisterForRemoteNotificationsthere when[FIRMessaging messaging].isAutoInitEnabledisYES), or resolve the auto-init flag without requiring aFIRAppinstance (Info.plistFirebaseMessagingAutoInitEnabled/ the persisted user default). Either restores the 16.4.3 behaviour for Dart-initialized apps while keeping the opt-in semantics #18452 intended.Reproducing the issue
firebase_options.dartgenerated byflutterfire configure,Firebase.initializeApp(options: ...)inmain(), noGoogleService-Info.plistin the iOS project, no nativeFirebaseApp.configure(). Method swizzling enabled (default).FirebaseMessagingAutoInitEnablednot set (defaults to enabled).firebase_messaging: 16.5.0(also reproduces on 16.6.0 andmain).Firebase.initializeApp(), pollFirebaseMessaging.instance.getAPNSToken()every second for 30 s.nullfor the whole period, andgetToken()throwingapns-token-not-set. Watch the unified log for theI-COR000003lines emitted at plugin setup.firebase_messaging: 16.4.3(and the matchingfirebase_core4.12.1 so the Firebase iOS SDK pins agree): the APNs token arrives within ~1 s of launch.Reproduces on an Apple silicon simulator (iPhone 17, iOS 26.5, which supports APNs) and on physical devices. UIScene vs. non-UIScene does not matter for this case.
Firebase Core version
4.13.0 (firebase_core_platform_interface 8.1.0, Firebase iOS SDK 12.17.0)
Flutter Version
3.44.9 (Dart 3.12.2), Xcode 26.6
Relevant Log Output
Flutter dependencies
Expand
Flutter dependenciessnippetAdditional context and comments
+[FIRMessaging messaging]returningnilbefore configure:FIRMessaging.m→[FIRApp defaultApp]→FIR_COMPONENT(FIRMessagingInterop, defaultApp.container);+[FIRApp defaultApp]logsI-COR000003and returnsnilwhensDefaultAppis unset.