From c644fe6a6b38ebff81601b85ca731e1f1e9bdd64 Mon Sep 17 00:00:00 2001 From: Victor Colomb <51762123+VictorColomb@users.noreply.github.com> Date: Wed, 17 Jan 2024 21:46:24 +0000 Subject: [PATCH 1/2] FirebaseMessagingService onNewToken for non-default Firebase apps --- .../firebase/messaging/FirebaseMessaging.java | 20 +++++++----------- .../messaging/FirebaseMessagingService.java | 21 ++++++++++++++++++- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessaging.java b/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessaging.java index a6a5c373dfe..4dadda00c20 100644 --- a/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessaging.java +++ b/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessaging.java @@ -641,19 +641,15 @@ boolean tokenNeedsRefresh(@Nullable Store.Token token) { } private void invokeOnTokenRefresh(String token) { - // onNewToken() is only invoked for the default app as there is no parameter to identify which - // app the token is for. We could add a new method onNewToken(FirebaseApp app, String token) or - // the like to handle multiple apps better. - if (FirebaseApp.DEFAULT_APP_NAME.equals(firebaseApp.getName())) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Invoking onNewToken for app: " + firebaseApp.getName()); - } - Intent messagingIntent = new Intent(FirebaseMessagingService.ACTION_NEW_TOKEN); - messagingIntent.putExtra(FirebaseMessagingService.EXTRA_TOKEN, token); - // Previously this sent to the FIIDReceiver, which forwarded to the service. - // Send directly to service using the old FIIDReceiver mechanism to keep the change simple. - new FcmBroadcastProcessor(context).process(messagingIntent); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Invoking onNewToken for app: " + firebaseApp.getName()); } + Intent messagingIntent = new Intent(FirebaseMessagingService.ACTION_NEW_TOKEN); + messagingIntent.putExtra(FirebaseMessagingService.EXTRA_TOKEN, token); + messagingIntent.putExtra(FirebaseMessagingService.EXTRA_TOKEN_APP_NAME, firebaseApp.getName()); + // Previously this sent to the FIIDReceiver, which forwarded to the service. + // Send directly to service using the old FIIDReceiver mechanism to keep the change simple. + new FcmBroadcastProcessor(context).process(messagingIntent); } private class AutoInit { diff --git a/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java b/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java index 7cc65379bfb..a940a52e5aa 100644 --- a/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java +++ b/firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java @@ -25,6 +25,7 @@ import androidx.annotation.WorkerThread; import com.google.android.gms.cloudmessaging.CloudMessage; import com.google.android.gms.cloudmessaging.Rpc; +import com.google.firebase.FirebaseApp; import com.google.firebase.messaging.Constants.MessagePayloadKeys; import com.google.firebase.messaging.Constants.MessageTypes; import java.util.ArrayDeque; @@ -74,6 +75,7 @@ public class FirebaseMessagingService extends EnhancedIntentService { static final String ACTION_NEW_TOKEN = "com.google.firebase.messaging.NEW_TOKEN"; static final String EXTRA_TOKEN = "token"; + static final String EXTRA_TOKEN_APP_NAME = "firebaseAppName"; private static final int RECENTLY_RECEIVED_MESSAGE_IDS_MAX_SIZE = 10; @@ -152,6 +154,19 @@ public void onSendError(@NonNull String msgId, @NonNull Exception exception) {} @WorkerThread public void onNewToken(@NonNull String token) {} + /** + * Called when a new token for the specified Firebase project is generated. + * + *

This is invoked after app install when a token is first generated, and again if the token + * changes. + * + * @param token The token used for sending messages to this application instance. This token is + * the same as the one retrieved by {@link FirebaseMessaging#getToken()}. + * @param firebaseAppName The name of the FirebaseApp instance for which the token was generated. + */ + @WorkerThread + public void onNewToken(@NonNull String token, @NonNull String firebaseAppName) {} + /** @hide */ @Override protected Intent getStartCommandIntent(Intent originalIntent) { @@ -167,7 +182,11 @@ public void handleIntent(Intent intent) { if (ACTION_REMOTE_INTENT.equals(action) || ACTION_DIRECT_BOOT_REMOTE_INTENT.equals(action)) { handleMessageIntent(intent); } else if (ACTION_NEW_TOKEN.equals(action)) { - onNewToken(intent.getStringExtra(EXTRA_TOKEN)); + String appName = intent.getStringExtra(EXTRA_TOKEN_APP_NAME); + onNewToken(intent.getStringExtra(EXTRA_TOKEN), appName); + if (appName == FirebaseApp.DEFAULT_APP_NAME) { + onNewToken(intent.getStringExtra(EXTRA_TOKEN)); + } } else { Log.d(TAG, "Unknown intent action: " + intent.getAction()); } From a4aca27c394a83bfa967893c832c0a9a4be2e85b Mon Sep 17 00:00:00 2001 From: Victor Colomb Date: Thu, 18 Jan 2024 10:26:27 +0100 Subject: [PATCH 2/2] Amend tests for the updated onNewToken method --- .../FirebaseMessagingServiceRoboTest.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/firebase-messaging/src/test/java/com/google/firebase/messaging/FirebaseMessagingServiceRoboTest.java b/firebase-messaging/src/test/java/com/google/firebase/messaging/FirebaseMessagingServiceRoboTest.java index 66915d6fd63..e810bd6bf0e 100644 --- a/firebase-messaging/src/test/java/com/google/firebase/messaging/FirebaseMessagingServiceRoboTest.java +++ b/firebase-messaging/src/test/java/com/google/firebase/messaging/FirebaseMessagingServiceRoboTest.java @@ -101,6 +101,7 @@ public class FirebaseMessagingServiceRoboTest { // Extra for the token within a NEW_TOKEN event private static final String EXTRA_TOKEN = "token"; + private static final String EXTRA_TOKEN_APP_NAME = "firebaseAppName"; // blank activity public static class MyTestActivity extends Activity {} @@ -344,9 +345,10 @@ public void testSendError_messageIdServer() throws Exception { } @Test - public void testOnNewToken() throws Exception { + public void testOnNewTokenDefault() throws Exception { Intent intent = new Intent(ACTION_NEW_TOKEN); intent.putExtra(EXTRA_TOKEN, "token123"); + intent.putExtra(EXTRA_TOKEN_APP_NAME, "[DEFAULT]"); ServiceStarter.getInstance().startMessagingService(context, intent); processInternalStartService(context); @@ -355,6 +357,19 @@ public void testOnNewToken() throws Exception { verify(service).onNewToken("token123"); } + @Test + public void testOnNewToken() throws Exception { + Intent intent = new Intent(ACTION_NEW_TOKEN); + intent.putExtra(EXTRA_TOKEN, "token123"); + intent.putExtra(EXTRA_TOKEN_APP_NAME, "customappname"); + + ServiceStarter.getInstance().startMessagingService(context, intent); + processInternalStartService(context); + flushTasks(); + + verify(service).onNewToken("token123", "customappname"); + } + /** * Test a notification message causes a notification to be posted, and none of the callbacks to be * invoked.