Skip to content

Commit a57837e

Browse files
authored
fix(messaging,android): skip onMessageOpenedApp for terminated notification taps (#18663)
Terminated launches already store the message for getInitialMessage(); also invoking the stream handled the same tap twice.
1 parent 8f0a5d0 commit a57837e

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

‎packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ public void onAttachedToActivity(ActivityPluginBinding binding) {
124124
// The notification tap created this Activity, so the Messaging SDK has already logged
125125
// `notification_open` from FcmLifecycleCallbacks#onActivityCreated. Handle the intent
126126
// without logging it a second time.
127-
handleNotificationIntent(mainActivity.getIntent());
127+
// Terminated launch: getInitialMessage() owns this tap. Do not also fire
128+
// onMessageOpenedApp (firebase/flutterfire#18661).
129+
handleNotificationIntent(mainActivity.getIntent(), /* shouldNotifyStream= */ false);
128130
}
129131
}
130132
}
@@ -630,7 +632,8 @@ public boolean onNewIntent(@NonNull Intent intent) {
630632
// FcmLifecycleCallbacks#onActivityCreated for this intent and `notification_open` was not
631633
// logged. Log it here before handling the intent.
632634
logNotificationOpen(intent);
633-
return handleNotificationIntent(intent);
635+
// Background resume: onMessageOpenedApp owns this tap.
636+
return handleNotificationIntent(intent, /* shouldNotifyStream= */ true);
634637
}
635638

636639
/**
@@ -700,7 +703,17 @@ private static String getMessageId(@NonNull Bundle extras) {
700703
return messageId;
701704
}
702705

703-
private boolean handleNotificationIntent(@NonNull Intent intent) {
706+
/**
707+
* Handles a notification-tap intent.
708+
*
709+
* <p>{@code shouldNotifyStream} is {@code false} when the tap created this Activity (terminated
710+
* launch). In that case the message is stored for {@code getInitialMessage()} only, matching iOS
711+
* and the Dart API docs. It is {@code true} when the Activity already existed ({@link
712+
* #onNewIntent}), which is a resume from background and should fire {@code onMessageOpenedApp}.
713+
*
714+
* @see <a href="https://github.com/firebase/flutterfire/issues/18661">#18661</a>
715+
*/
716+
private boolean handleNotificationIntent(@NonNull Intent intent, boolean shouldNotifyStream) {
704717
if (intent.getExtras() == null) {
705718
return false;
706719
}
@@ -740,7 +753,10 @@ private boolean handleNotificationIntent(@NonNull Intent intent) {
740753
message.put("notification", initialMessageNotification);
741754
}
742755

743-
channel.invokeMethod("Messaging#onMessageOpenedApp", message);
756+
// On a terminated launch, getInitialMessage() owns this message.
757+
if (shouldNotifyStream) {
758+
channel.invokeMethod("Messaging#onMessageOpenedApp", message);
759+
}
744760
mainActivity.setIntent(intent);
745761
return true;
746762
}

0 commit comments

Comments
 (0)