diff --git a/firebase-installations/src/main/java/com/google/firebase/installations/FirebaseInstallations.java b/firebase-installations/src/main/java/com/google/firebase/installations/FirebaseInstallations.java index d0edf5240bc..346196b3ef3 100644 --- a/firebase-installations/src/main/java/com/google/firebase/installations/FirebaseInstallations.java +++ b/firebase-installations/src/main/java/com/google/firebase/installations/FirebaseInstallations.java @@ -392,9 +392,11 @@ private void doNetworkCallIfNecessary(boolean forceRefresh) { // be registered with the server or the FID is registered but we need a fresh authtoken. // Registering will also result in a fresh authtoken. Do the appropriate step here. PersistedInstallationEntry updatedPrefs; + boolean isNewFID = false; try { if (prefs.isErrored() || prefs.isUnregistered()) { updatedPrefs = registerFidWithServer(prefs); + isNewFID = true; } else if (forceRefresh || utils.isAuthTokenExpired(prefs)) { updatedPrefs = fetchAuthTokenFromServer(prefs); } else { @@ -409,8 +411,12 @@ private void doNetworkCallIfNecessary(boolean forceRefresh) { // Store the prefs to persist the result of the previous step. insertOrUpdatePrefs(updatedPrefs); - // Update FidListener if a fid has changed. - updateFidListener(prefs, updatedPrefs); + // Update FidListener if a fid is new or has changed. + if (isNewFID + || !TextUtils.equals( + prefs.getFirebaseInstallationId(), updatedPrefs.getFirebaseInstallationId())) { + updateFidListener(updatedPrefs); + } prefs = updatedPrefs; @@ -431,11 +437,10 @@ private void doNetworkCallIfNecessary(boolean forceRefresh) { } } - private synchronized void updateFidListener( - PersistedInstallationEntry prefs, PersistedInstallationEntry updatedPrefs) { - if (fidListeners.size() != 0 - && !TextUtils.equals( - prefs.getFirebaseInstallationId(), updatedPrefs.getFirebaseInstallationId())) { + private synchronized void updateFidListener(@NonNull PersistedInstallationEntry updatedPrefs) { + if (!fidListeners.isEmpty() + && !TextUtils.isEmpty(updatedPrefs.getFirebaseInstallationId()) + && updatedPrefs.isRegistered()) { // Update all the registered FidListener about fid changes. for (FidListener listener : fidListeners) { listener.onFidChanged(updatedPrefs.getFirebaseInstallationId()); diff --git a/firebase-installations/src/test/java/com/google/firebase/installations/FirebaseInstallationsTest.java b/firebase-installations/src/test/java/com/google/firebase/installations/FirebaseInstallationsTest.java index e344c9459eb..8fd55f580aa 100644 --- a/firebase-installations/src/test/java/com/google/firebase/installations/FirebaseInstallationsTest.java +++ b/firebase-installations/src/test/java/com/google/firebase/installations/FirebaseInstallationsTest.java @@ -500,6 +500,65 @@ public void testFidListener_fidChanged_successful() throws Exception { assertNull(fidListener2.getLatestFid()); } + @Test + public void testFidListener_fidRegistered_sameFid_successful() throws Exception { + when(mockIidStore.readIid()).thenReturn(null); + when(mockIidStore.readToken()).thenReturn(null); + when(mockBackend.createFirebaseInstallation( + anyString(), anyString(), anyString(), anyString(), any())) + .thenReturn(TEST_INSTALLATION_RESPONSE); + + FakeFidListener fidListener = new FakeFidListener(); + + // Register the FidListener + firebaseInstallations.registerFidListener(fidListener); + + // Do the actual getId() call under test. + TestOnCompleteListener onCompleteListener = new TestOnCompleteListener<>(); + Task task = firebaseInstallations.getId(); + + task.addOnCompleteListener(backgroundExecutor, onCompleteListener); + String fid = onCompleteListener.await(); + assertWithMessage("getId Task failed.").that(fid).isEqualTo(TEST_FID_1); + + // Waiting for Task that registers FID on the FIS Servers + backgroundExecutor.awaitTermination(500, TimeUnit.MILLISECONDS); + PersistedInstallationEntry entry = persistedInstallation.readPersistedInstallationEntryValue(); + assertThat(entry.getFirebaseInstallationId()).isEqualTo(TEST_FID_1); + + // Verify FidListener receives fid registration notification. + assertThat(fidListener.getLatestFid()).isEqualTo(TEST_FID_1); + } + + @Test + public void testFidListener_alreadyRegistered_noFidChange_notNotified() throws Exception { + persistedInstallation.insertOrUpdatePersistedInstallationEntry( + PersistedInstallationEntry.INSTANCE.withRegisteredFid( + TEST_FID_1, + TEST_REFRESH_TOKEN, + utils.currentTimeInSecs(), + TEST_AUTH_TOKEN, + TEST_TOKEN_EXPIRATION_TIMESTAMP)); + + FakeFidListener fidListener = new FakeFidListener(); + + // Register the FidListener + firebaseInstallations.registerFidListener(fidListener); + + // Do the actual getId() call under test. + TestOnCompleteListener onCompleteListener = new TestOnCompleteListener<>(); + Task task = firebaseInstallations.getId(); + task.addOnCompleteListener(backgroundExecutor, onCompleteListener); + String fid = onCompleteListener.await(); + assertWithMessage("getId Task failed.").that(fid).isEqualTo(TEST_FID_1); + + backgroundExecutor.awaitTermination(500, TimeUnit.MILLISECONDS); + + // Verify FidListener does not receive any notification since the FID was already registered + // and didn't change. + assertNull(fidListener.getLatestFid()); + } + @Test public void testGetId_migrateIid_successful() throws Exception { when(mockIidStore.readIid()).thenReturn(TEST_INSTANCE_ID_1);