Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ @implementation FLTFirebaseMessagingPlugin {
BOOL _notificationHandlingSetup;
BOOL _applicationObserverRegistered;

// Set once APNs registration has been requested because FCM auto-init is enabled, so the
// auto-init check is not re-run (and registerForRemoteNotifications not re-issued) on every
// Firebase app initialization.
BOOL _apnsRegistrationRequested;

#if TARGET_OS_OSX
// Tracks when plugin registration occurred after the macOS launch notification.
BOOL _missedApplicationDidFinishLaunchingNotification;
Expand Down Expand Up @@ -273,6 +278,36 @@ - (void)registerForRemoteNotifications {
#endif
}

// Registers for APNs if FCM auto-init is enabled. Registration is deferred while auto-init is
// disabled so the APNs token cannot trigger FCM registration before the user opts in (see
// `messagingSetAutoInitEnabled:`, which registers once they do).
//
// `[FIRMessaging messaging]` requires a configured default FIRApp. When Firebase is initialized
// from Dart (`Firebase.initializeApp(options:)` with no GoogleService-Info.plist / native
// `FirebaseApp.configure()`), the default app does not exist yet at launch, so `[FIRMessaging
// messaging]` is nil and `isAutoInitEnabled` reads as NO. In that case the check is skipped here
// and re-run from `pluginConstantsForFIRApp:` once Dart has configured the app.
//
// Safe to call repeatedly: APNs registration is only requested once per process.
- (void)registerForRemoteNotificationsIfAutoInitEnabled {
if (_apnsRegistrationRequested) {
return;
}
// Checked via FIRApp.allApps rather than `[FIRApp defaultApp]` / `[FIRMessaging messaging]` so
// a not-yet-configured app does not log the misleading "default Firebase app has not yet been
// configured" (I-COR000003) warning during launch.
if ([FLTFirebasePlugin firebaseAppNamed:@"[DEFAULT]"] == nil) {
return;
}
if (![FIRMessaging messaging].isAutoInitEnabled) {
return;
}
_apnsRegistrationRequested = YES;
[self registerForRemoteNotifications];
// Forward an APNs token that may have arrived before Firebase was configured.
[self ensureAPNSTokenSetting];
}

#ifdef __FF_NOTIFICATIONS_SUPPORTED_PLATFORM
- (void)configureNotificationCenterDelegate {
// Set UNUserNotificationCenter but preserve original delegate if necessary.
Expand Down Expand Up @@ -416,11 +451,9 @@ - (void)setupNotificationHandlingWithRemoteNotification:(nullable NSDictionary *
// We automatically register for remote notifications as
// application:didReceiveRemoteNotification:fetchCompletionHandler: will not get called unless
// registerForRemoteNotifications is called early on during app initialization, calling this from
// Dart would be too late. Defer registration when auto-init is disabled so the APNs token cannot
// trigger FCM registration before the user opts in.
if ([FIRMessaging messaging].isAutoInitEnabled) {
[self registerForRemoteNotifications];
}
// Dart would be too late. Registration is skipped when auto-init is disabled, or deferred to
// `pluginConstantsForFIRApp:` when Firebase has not been configured natively yet.
[self registerForRemoteNotificationsIfAutoInitEnabled];
}

- (void)markInitialNotificationGatheredAfterDelay {
Expand Down Expand Up @@ -785,6 +818,7 @@ - (void)messagingSetAutoInitEnabled:(id)arguments
BOOL enabled = [arguments[@"enabled"] boolValue];
messaging.autoInitEnabled = enabled;
if (enabled) {
_apnsRegistrationRequested = YES;
[self registerForRemoteNotifications];
[self ensureAPNSTokenSetting];
}
Expand Down Expand Up @@ -915,6 +949,10 @@ - (void)didReinitializeFirebaseCore:(void (^)(void))completion {
}

- (NSDictionary *_Nonnull)pluginConstantsForFIRApp:(FIRApp *)firebase_app {
// Called by firebase_core right after `Firebase.initializeApp()` has configured the app. For
// apps initialized from Dart this is the first point where `[FIRMessaging messaging]` exists,
// so re-run the auto-init check that was skipped during launch.
[self registerForRemoteNotificationsIfAutoInitEnabled];
return @{
@"AUTO_INIT_ENABLED" : @([FIRMessaging messaging].isAutoInitEnabled),
};
Expand Down
Loading