Skip to content

Commit 1375b05

Browse files
committed
fix(firebase_messaging): improve scene delegate support for notification handling
1 parent 56c1262 commit 1375b05

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

packages/firebase_messaging/firebase_messaging/ios/firebase_messaging/Sources/firebase_messaging/FLTFirebaseMessagingPlugin.m

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ @implementation FLTFirebaseMessagingPlugin {
4040
NSString *_notificationOpenedAppID;
4141
NSString *_foregroundUniqueIdentifier;
4242

43+
// Track if scene delegate connected (for iOS 13+ scene delegate support)
44+
BOOL _sceneDidConnect;
45+
4346
#ifdef __FF_NOTIFICATIONS_SUPPORTED_PLATFORM
4447
API_AVAILABLE(ios(10), macosx(10.14))
4548
__weak id<UNUserNotificationCenterDelegate> _originalNotificationCenterDelegate;
@@ -59,6 +62,7 @@ - (instancetype)initWithFlutterMethodChannel:(FlutterMethodChannel *)channel
5962
self = [super init];
6063
if (self) {
6164
_initialNotificationGathered = NO;
65+
_sceneDidConnect = NO;
6266
_channel = channel;
6367
_registrar = registrar;
6468
// Application
@@ -223,9 +227,24 @@ - (void)setupNotificationHandlingWithRemoteNotification:
223227
_initialNotification =
224228
[FLTFirebaseMessagingPlugin remoteMessageUserInfoToDict:remoteNotification];
225229
_initialNotificationID = remoteNotification[@"gcm.message_id"];
230+
_initialNotificationGathered = YES;
231+
[self initialNotificationCallback];
232+
} else if (_sceneDidConnect) {
233+
// For scene delegates, if no notification was found in connectionOptions,
234+
// delay marking as gathered to allow didReceiveRemoteNotification to fire first
235+
// for contentAvailable notifications that caused the app to launch
236+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),
237+
dispatch_get_main_queue(), ^{
238+
if (!self->_initialNotificationGathered) {
239+
self->_initialNotificationGathered = YES;
240+
[self initialNotificationCallback];
241+
}
242+
});
243+
} else {
244+
// For non-scene delegate apps, mark as gathered immediately
245+
_initialNotificationGathered = YES;
246+
[self initialNotificationCallback];
226247
}
227-
_initialNotificationGathered = YES;
228-
[self initialNotificationCallback];
229248

230249
[GULAppDelegateSwizzler registerAppDelegateInterceptor:self];
231250
[GULAppDelegateSwizzler proxyOriginalDelegateIncludingAPNSMethods];
@@ -478,6 +497,15 @@ - (BOOL)application:(UIApplication *)application
478497
[FLTFirebaseMessagingPlugin remoteMessageUserInfoToDict:userInfo];
479498
// Only handle notifications from FCM.
480499
if (userInfo[@"gcm.message_id"]) {
500+
// For scene delegate apps: if this notification arrives during cold launch
501+
// (before initial notification gathering is complete) and no notification was found
502+
// in connectionOptions, this is the notification that caused the launch.
503+
if (_sceneDidConnect && !_initialNotificationGathered && _initialNotification == nil) {
504+
_initialNotification = notificationDict;
505+
_initialNotificationID = userInfo[@"gcm.message_id"];
506+
_initialNotificationGathered = YES;
507+
[self initialNotificationCallback];
508+
}
481509
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
482510
__block BOOL completed = NO;
483511

@@ -548,6 +576,7 @@ - (void)scene:(UIScene *)scene
548576
options:(UISceneConnectionOptions *)connectionOptions {
549577
// Handle launch notification if present
550578
// With scene delegates, the notification can be in notificationResponse if user tapped it
579+
_sceneDidConnect = YES;
551580

552581
NSDictionary *remoteNotification = nil;
553582
if (connectionOptions.notificationResponse != nil) {

0 commit comments

Comments
 (0)