Conversation
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
Only conflict was the explanatory comment above the Messaging#startBackgroundIsolate case. Kept this branch's updated wording (the eager start it described is gone) at main's reindented column, since main reformatted that block from 8 to 6 spaces.
…kground executor Removing the eager background-isolate start left FlutterShellArgs always null: the only remaining caller is the lazy path in FlutterFirebaseMessagingBackgroundService.onCreate(), which goes through the no-arg startBackgroundIsolate() and passed null explicitly. Collapses the shellArgs parameter and its unreachable branch, and drops the two imports that became unused. This does not reopen #4078. That was a ClassCastException from casting FlutterFragmentActivity to FlutterActivity to reach getFlutterShellArgs(); #4341 fixed it by switching to FlutterShellArgs.fromIntent(). With the activity no longer consulted at all, the cast that caused #4078 is gone.
The minSdk = 23 -> flutter.minSdkVersion change was unrelated to the duplicate-call-stack fix, and it breaks the example on the oldest Flutter this package supports. pubspec declares flutter: '>=3.27.0', where FlutterExtension.minSdkVersion is 21, while firebase_messaging's local-config.gradle sets minSdk=23 -- so the manifest merger fails with "minSdkVersion 21 cannot be smaller than version 23 declared in library". CI only runs stable (currently 3.44.6, where the default is 24), so the break would not show up here. Nine other example apps hardcode minSdk = 23 for the same reason.
…olate keeps them The eager background-isolate start was the only place with access to an activity, so removing it left the background engine with no shell args at all. Instead of dropping them, capture them at registration -- where an activity is still available -- and persist them next to the callback handles already stored in SharedPreferences. The lazy start in FlutterFirebaseMessagingBackgroundService.onCreate() then restores them. This is strictly wider coverage than before: previously the killed-app path (the common background case) already started the isolate through the no-arg overload with null args, so shell args only applied when an activity happened to be alive. Now they apply in both paths. Stored as a JSON array rather than a String set because arg order is significant. org.json is already used by FlutterFirebaseMessagingStore. Passing null or empty clears the stored value, so args cannot go stale across a launch that has no activity.
…anifest flags Reverts the SharedPreferences plumbing added to carry FlutterShellArgs into the lazily-started background isolate, and documents the forward path instead. FlutterShellArgs is @deprecated upstream with a TODO to delete it once engine args via Intent are unsupported (flutter/flutter#180686). Its documented replacement, FlutterEngineFlags, reads flags from <application> metadata in AndroidManifest.xml -- and FlutterLoader applies those inside ensureInitializationComplete, which this executor already calls. So manifest-declared flags reach the background engine with no plugin code at all. FlutterEngineFlags cannot be referenced directly: it first shipped in Flutter 3.44.0, while this package supports flutter: '>=3.27.0'. Naming it would break compilation on 3.27 through 3.43, and CI only runs stable so that would not be caught here. Net effect: no deprecated API, less code, and engine flags handled by the mechanism Flutter is standardising on.
The background isolate runs in its own FlutterEngine started from a service, so command-line engine flags never reached it, and the intent-based mechanism that partially covered this is deprecated upstream (flutter/flutter#180686). Documents the supported replacement: <application> metadata in AndroidManifest.xml, which FlutterLoader applies to every engine it initializes. Notes the Flutter 3.44.0 floor, the mandatory io.flutter.embedding.android. prefix, that most flags are ignored in release builds, and that the command line wins over the manifest.
Description
When
FirebaseMessaging.onBackgroundMessage()was called on Android, the plugin eagerly started a background Dart isolate (FlutterEngine) at registration time, causing a duplicatemainin the call stack and running app initialization twice. This fix defers isolate creation to when a background message actually arrives and theFlutterFirebaseMessagingBackgroundServiceis started.Related Issues
mainin Call Stack on Android when UsingFirebaseMessaging.onBackgroundMessage#17163Checklist
///).melos run analyze) does not report any problems on my PR.Breaking Change