Repository navigation
Conversation
…st receiver When firebase-messaging displays a notification for a message that has analytics enabled, it gives the notification a delete intent. Dismissing the notification sends that intent: a com.google.android.c2dm.intent.RECEIVE broadcast to the app's package, with the NOTIFICATION_DISMISS intent in the wrapped_intent extra. Since firebase-messaging 23.3.1 (firebase-android-sdk #5410) it is addressed by action and package rather than to FirebaseInstanceIdReceiver, so FlutterFirebaseMessagingReceiver gets it too and built an empty RemoteMessage from it: onMessage in the foreground, onBackgroundMessage otherwise. The receiver now reads the message through remoteMessageFrom, which returns null for a broadcast whose wrapped_intent extra is an Intent, the check CloudMessagingReceiver (play-services-cloud-messaging) makes before treating a broadcast as a message. Firebase's receiver still logs the dismissal. The e2e test has the SDK build the notification (CommonNotificationBuilder, through reflection since it is hidden API) and sends its delete intent as an ordered broadcast. It then checks that Firebase's own receiver handled it (RESULT_OK), and that onMessage receives no message without an ID before the next message. Verified on an API 36 emulator with BoM 35.1.0: without the fix onMessage receives [null, <message ID>].
FCM also sends com.google.android.c2dm.intent.RECEIVE broadcasts that are not messages, marked by a message_type extra: deleted_messages when FCM has deleted messages pending for the app, and send_event and send_error about upstream messages. FirebaseMessagingService passes a broadcast to onMessageReceived only if it has no message type or "gcm", but FlutterFirebaseMessagingReceiver turned these into RemoteMessages for onMessage or onBackgroundMessage. remoteMessageFrom now returns null for any type other than "gcm", as the service drops them or passes them to their own callbacks. Behaviour change: apps that checked messageType == 'deleted_messages' in onMessage or onBackgroundMessage no longer get that broadcast, and the plugin has no other way to report it, as with onMessageReceived in native apps. These broadcasts no longer start a background isolate either. The e2e test hands the receiver a deleted_messages broadcast, then a message, and checks that onMessage receives only the message. Verified on an API 36 emulator: without the fix onMessage receives both.
Contributor
There was a problem hiding this comment.
Code Review
This pull request refactors FlutterFirebaseMessagingReceiver to extract message parsing into a helper method remoteMessageFrom, which filters out notification dismissals and non-gcm message types (such as deleted_messages). It also adds corresponding unit and integration tests. Feedback highlights a security and stability concern where parsing untrusted intents on this exported receiver could lead to a BadParcelableException and crash the app; wrapping these intent operations in try-catch blocks is recommended.
Lyokone
marked this pull request as ready for review
November 5, 2026 13:35
demolaf
approved these changes
Nov 5, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On Android, two broadcasts that carry no message reach
onMessagein the foreground, oronBackgroundMessageotherwise, as aRemoteMessagewith no message ID:messageTypedeleted_messages.Both use the broadcast action messages use, which the plugin's receiver listens to. Firebase's own receiver and service treat neither as a message.
Fix: the receiver now makes Firebase's checks before reading a message. It ignores a broadcast that wraps a notification event, and one whose message type is anything other than a message's (
deleted_messages, and the upstreamsend_eventandsend_error). Real messages are unaffected.Behaviour change: apps that looked for
messageType == 'deleted_messages'inonMessageoronBackgroundMessageno longer receive it, and the plugin has no other way to report it, as withonMessageReceivedin native Android apps.Tests
FlutterFirebaseMessagingReceiverTest(Android unit tests):ignoresABroadcastWrappingAnIntent,ignoresADeletedMessagesBroadcastandignoresMessageTypesOtherThanGcmfail without the fix. The other four check that messages still get through.dismissing a notification displayed by Firebase does not reach onMessageanda deleted messages broadcast does not reach onMessagefail without the fix:onMessagereceives the broadcast before the next message.Related Issues
Checklist
///).melos run analyze) does not report any problems on my PR.Breaking Change