Skip to content

Commit 5b60210

Browse files
authored
fix(messaging,ios): fix an issue where the scene initializer could be called twice in latest Flutter versions (#18051)
* fix(messaging,ios): fix an issue where the scene initializer could be called twice in latest Flutter versions * format
1 parent 1e39ad1 commit 5b60210

1 file changed

Lines changed: 30 additions & 0 deletions

File tree

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ @implementation FLTFirebaseMessagingPlugin {
4343
// Track if scene delegate connected (for iOS 13+ scene delegate support)
4444
BOOL _sceneDidConnect;
4545

46+
// Guard against calling setupNotificationHandling twice
47+
BOOL _notificationHandlingSetup;
48+
4649
#ifdef __FF_NOTIFICATIONS_SUPPORTED_PLATFORM
4750
API_AVAILABLE(ios(10), macosx(10.14))
4851
__weak id<UNUserNotificationCenterDelegate> _originalNotificationCenterDelegate;
@@ -63,6 +66,7 @@ - (instancetype)initWithFlutterMethodChannel:(FlutterMethodChannel *)channel
6366
if (self) {
6467
_initialNotificationGathered = NO;
6568
_sceneDidConnect = NO;
69+
_notificationHandlingSetup = NO;
6670
_channel = channel;
6771
_registrar = registrar;
6872
// Application
@@ -222,6 +226,32 @@ - (void)messaging:(nonnull FIRMessaging *)messaging
222226

223227
- (void)setupNotificationHandlingWithRemoteNotification:
224228
(nullable NSDictionary *)remoteNotification {
229+
// If notification handling was already set up (e.g. from
230+
// application_onDidFinishLaunchingNotification) and we're called again (e.g. from
231+
// scene:willConnectToSession:), only process the notification but skip delegate/swizzler
232+
// re-registration to avoid _originalNotificationCenterDelegate being set to self, which causes
233+
// infinite recursion in didReceiveNotificationResponse. See #18037.
234+
if (_notificationHandlingSetup) {
235+
if (remoteNotification != nil) {
236+
_initialNotification =
237+
[FLTFirebaseMessagingPlugin remoteMessageUserInfoToDict:remoteNotification];
238+
_initialNotificationID = remoteNotification[@"gcm.message_id"];
239+
_initialNotificationGathered = YES;
240+
[self initialNotificationCallback];
241+
} else if (_sceneDidConnect && !_initialNotificationGathered) {
242+
// Scene connected with no notification — delay to allow didReceiveRemoteNotification
243+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),
244+
dispatch_get_main_queue(), ^{
245+
if (!self->_initialNotificationGathered) {
246+
self->_initialNotificationGathered = YES;
247+
[self initialNotificationCallback];
248+
}
249+
});
250+
}
251+
return;
252+
}
253+
_notificationHandlingSetup = YES;
254+
225255
if (remoteNotification != nil) {
226256
// If remoteNotification exists, it is the notification that opened the app.
227257
_initialNotification =

0 commit comments

Comments
 (0)