diff --git a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingBackgroundService.java b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingBackgroundService.java index 6b75fa2ad6e5..1646af47fc8c 100644 --- a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingBackgroundService.java +++ b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingBackgroundService.java @@ -9,7 +9,6 @@ import android.os.Handler; import android.util.Log; import androidx.annotation.NonNull; -import io.flutter.embedding.engine.FlutterShellArgs; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -37,28 +36,6 @@ public static void enqueueMessageProcessing( isHighPriority); } - /** - * Starts the background isolate for the {@link FlutterFirebaseMessagingBackgroundService}. - * - *

Preconditions: - * - *

- */ - @SuppressWarnings("JavadocReference") - public static void startBackgroundIsolate(long callbackHandle, FlutterShellArgs shellArgs) { - if (flutterBackgroundExecutor != null) { - Log.w(TAG, "Attempted to start a duplicate background isolate. Returning..."); - return; - } - flutterBackgroundExecutor = new FlutterFirebaseMessagingBackgroundExecutor(); - flutterBackgroundExecutor.startBackgroundIsolate(callbackHandle, shellArgs); - } - /** * Called once the Dart isolate ({@code flutterBackgroundExecutor}) has finished initializing. * diff --git a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java index 63d1e0dfac0a..d3832680e80c 100644 --- a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java @@ -23,7 +23,6 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.RemoteMessage; -import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; @@ -421,12 +420,9 @@ public void onMethodCall(final MethodCall call, @NonNull final Result result) { Task methodCallTask; switch (call.method) { - // This message is sent when the Dart side of this plugin is told to initialize. - // In response, this (native) side of the plugin needs to spin up a background - // Dart isolate by using the given pluginCallbackHandle, and then setup a background - // method channel to communicate with the new background isolate. Once completed, - // this onMethodCall() method will receive messages from both the primary and background - // method channels. + // This message is sent when the Dart side of this plugin registers a background + // message handler. We persist the callback handles to SharedPreferences so + // the background service can start the isolate later when a message arrives. case "Messaging#startBackgroundIsolate": @SuppressWarnings("unchecked") Map arguments = ((Map) call.arguments); @@ -455,19 +451,13 @@ public void onMethodCall(final MethodCall call, @NonNull final Result result) { "Expected 'Long' or 'Integer' type for 'userCallbackHandle'."); } - FlutterShellArgs shellArgs = null; - if (mainActivity != null) { - // Supports both Flutter Activity types: - // io.flutter.embedding.android.FlutterFragmentActivity - // io.flutter.embedding.android.FlutterActivity - // We could use `getFlutterShellArgs()` but this is only available on `FlutterActivity`. - shellArgs = FlutterShellArgs.fromIntent(mainActivity.getIntent()); - } - + // Only save the callback handles to SharedPreferences. Don't start the + // background isolate here — it will be started lazily in + // FlutterFirebaseMessagingBackgroundService.onCreate() when a background + // message actually arrives and the service is started. Starting it eagerly + // caused a duplicate Dart main() to appear in the call stack (#17163). FlutterFirebaseMessagingBackgroundService.setCallbackDispatcher(pluginCallbackHandle); FlutterFirebaseMessagingBackgroundService.setUserCallbackHandle(userCallbackHandle); - FlutterFirebaseMessagingBackgroundService.startBackgroundIsolate( - pluginCallbackHandle, shellArgs); methodCallTask = Tasks.forResult(null); break; case "Messaging#getInitialMessage": diff --git a/packages/firebase_messaging/firebase_messaging/example/android/app/build.gradle b/packages/firebase_messaging/firebase_messaging/example/android/app/build.gradle index 8ebdee7a1533..3c01572f5225 100644 --- a/packages/firebase_messaging/firebase_messaging/example/android/app/build.gradle +++ b/packages/firebase_messaging/firebase_messaging/example/android/app/build.gradle @@ -47,7 +47,7 @@ android { applicationId = "io.flutter.plugins.firebase.messaging.example" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdk = 23 + minSdkVersion = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion versionCode = flutterVersionCode.toInteger() versionName = flutterVersionName