Skip to content

Reuse existing Iid as Fid #924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 25, 2019
5 changes: 5 additions & 0 deletions firebase-installations/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ package com.google.firebase.installations {

package com.google.firebase.installations.local {

public class IidStore {
ctor public IidStore(@NonNull FirebaseApp);
method @Nullable public String readIid();
}

public class PersistedInstallation {
ctor public PersistedInstallation(@NonNull FirebaseApp);
method @NonNull public boolean clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_CREATION_TIMESTAMP_2;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_FID_1;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_INSTALLATION_RESPONSE;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_INSTALLATION_RESPONSE_WITH_IID;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_INSTALLATION_TOKEN_RESULT;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_INSTANCE_ID_1;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_PROJECT_ID;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_REFRESH_TOKEN;
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_TOKEN_EXPIRATION_TIMESTAMP;
Expand All @@ -52,6 +54,7 @@
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseException;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.installations.local.IidStore;
import com.google.firebase.installations.local.PersistedInstallation;
import com.google.firebase.installations.local.PersistedInstallation.RegistrationStatus;
import com.google.firebase.installations.local.PersistedInstallationEntry;
Expand Down Expand Up @@ -88,6 +91,7 @@ public class FirebaseInstallationsInstrumentedTest {
@Mock private Utils mockUtils;
@Mock private PersistedInstallation mockPersistedInstallation;
@Mock private FirebaseInstallationServiceClient mockClient;
@Mock private IidStore mockIidStore;

private static final PersistedInstallationEntry REGISTERED_INSTALLATION_ENTRY =
PersistedInstallationEntry.builder()
Expand All @@ -99,6 +103,16 @@ public class FirebaseInstallationsInstrumentedTest {
.setRegistrationStatus(PersistedInstallation.RegistrationStatus.REGISTERED)
.build();

private static final PersistedInstallationEntry REGISTERED_IID_ENTRY =
PersistedInstallationEntry.builder()
.setFirebaseInstallationId(TEST_INSTANCE_ID_1)
.setAuthToken(TEST_AUTH_TOKEN)
.setRefreshToken(TEST_REFRESH_TOKEN)
.setTokenCreationEpochInSecs(TEST_CREATION_TIMESTAMP_2)
.setExpiresInSecs(TEST_TOKEN_EXPIRATION_TIMESTAMP)
.setRegistrationStatus(PersistedInstallation.RegistrationStatus.REGISTERED)
.build();

private static final PersistedInstallationEntry EXPIRED_AUTH_TOKEN_ENTRY =
PersistedInstallationEntry.builder()
.setFirebaseInstallationId(TEST_FID_1)
Expand Down Expand Up @@ -182,6 +196,8 @@ public void setUp() throws FirebaseException {
doThrow(new FirebaseException("Server Error"))
.when(backendClientReturnsError)
.deleteFirebaseInstallation(anyString(), anyString(), anyString(), anyString());

when(mockIidStore.readIid()).thenReturn(null);
}

@After
Expand All @@ -191,10 +207,15 @@ public void cleanUp() throws Exception {

@Test
public void testGetId_PersistedInstallationOk_BackendOk() throws Exception {
when(mockUtils.isAuthTokenExpired(REGISTERED_INSTALLATION_ENTRY)).thenReturn(false);
when(mockUtils.isAuthTokenExpired(REGISTERED_IID_ENTRY)).thenReturn(false);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

// No exception, means success.
assertWithMessage("getId Task failed.")
Expand All @@ -213,6 +234,39 @@ public void testGetId_PersistedInstallationOk_BackendOk() throws Exception {
assertThat(updatedInstallationEntry).hasRegistrationStatus(RegistrationStatus.REGISTERED);
}

@Test
public void testGetId_migrateIid_successful() throws Exception {
when(mockIidStore.readIid()).thenReturn(TEST_INSTANCE_ID_1);
when(mockUtils.isAuthTokenExpired(REGISTERED_INSTALLATION_ENTRY)).thenReturn(false);
when(backendClientReturnsOk.createFirebaseInstallation(
anyString(), anyString(), anyString(), anyString()))
.thenReturn(TEST_INSTALLATION_RESPONSE_WITH_IID);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

// No exception, means success.
assertWithMessage("getId Task failed.")
.that(Tasks.await(firebaseInstallations.getId()))
.isNotEmpty();
PersistedInstallationEntry entryValue =
persistedInstallation.readPersistedInstallationEntryValue();
assertThat(entryValue).hasFid(TEST_INSTANCE_ID_1);

// Waiting for Task that registers FID on the FIS Servers
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this have to wait half a second?
Are we actually sending a request to FIS here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is for getId(). As you know, getId() return fid immediately but registers fid asynchronously. Tests have to wait for half a second while we mock registration. We dont send an actual request to FIS in tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to add this explanation to the comment in the code.
Also, 500ms sounds excessive, but can't hurt maybe... :)


PersistedInstallationEntry updatedInstallationEntry =
persistedInstallation.readPersistedInstallationEntryValue();
assertThat(updatedInstallationEntry).hasFid(TEST_INSTANCE_ID_1);
assertThat(updatedInstallationEntry).hasRegistrationStatus(RegistrationStatus.REGISTERED);
}

@Test
public void testGetId_multipleCalls_sameFIDReturned() throws Exception {
when(mockUtils.isAuthTokenExpired(REGISTERED_INSTALLATION_ENTRY)).thenReturn(false);
Expand All @@ -221,7 +275,12 @@ public void testGetId_multipleCalls_sameFIDReturned() throws Exception {
.thenReturn(TEST_INSTALLATION_RESPONSE);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

// Call getId multiple times
Task<String> task1 = firebaseInstallations.getId();
Expand Down Expand Up @@ -251,7 +310,12 @@ public void testGetId_invalidFid_storesValidFidFromResponse() throws Exception {
when(mockUtils.isAuthTokenExpired(REGISTERED_INSTALLATION_ENTRY)).thenReturn(false);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

// No exception, means success.
assertWithMessage("getId Task failed.")
Expand All @@ -275,7 +339,12 @@ public void testGetId_invalidFid_storesValidFidFromResponse() throws Exception {
public void testGetId_PersistedInstallationOk_BackendError() throws Exception {
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsError, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsError,
persistedInstallation,
mockUtils,
mockIidStore);

Tasks.await(firebaseInstallations.getId());

Expand All @@ -301,7 +370,12 @@ public void testGetId_ServerError_UnregisteredFID() throws Exception {

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

Tasks.await(firebaseInstallations.getId());

Expand All @@ -326,7 +400,8 @@ public void testGetId_PersistedInstallationError_BackendOk() throws InterruptedE
firebaseApp,
backendClientReturnsOk,
persistedInstallationReturnsError,
mockUtils);
mockUtils,
mockIidStore);

// Expect exception
try {
Expand Down Expand Up @@ -355,7 +430,7 @@ public void testGetId_fidRegistrationUncheckedException_statusUpdated() throws E

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, mockClient, persistedInstallation, mockUtils);
executor, firebaseApp, mockClient, persistedInstallation, mockUtils, mockIidStore);

Tasks.await(firebaseInstallations.getId());

Expand Down Expand Up @@ -387,7 +462,7 @@ public void testGetId_expiredAuthTokenUncheckedException_statusUpdated() throws

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, mockClient, persistedInstallation, mockUtils);
executor, firebaseApp, mockClient, persistedInstallation, mockUtils, mockIidStore);

assertWithMessage("getId Task failed")
.that(Tasks.await(firebaseInstallations.getId()))
Expand All @@ -414,7 +489,12 @@ public void testGetId_expiredAuthToken_refreshesAuthToken() throws Exception {

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

assertWithMessage("getId Task failed")
.that(Tasks.await(firebaseInstallations.getId()))
Expand All @@ -441,7 +521,12 @@ public void testGetAuthToken_fidDoesNotExist_successful() throws Exception {
when(mockUtils.isAuthTokenExpired(REGISTERED_INSTALLATION_ENTRY)).thenReturn(false);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

Tasks.await(firebaseInstallations.getAuthToken(FirebaseInstallationsApi.DO_NOT_FORCE_REFRESH));

Expand All @@ -459,7 +544,8 @@ public void testGetAuthToken_PersistedInstallationError_failure() throws Excepti
firebaseApp,
backendClientReturnsOk,
persistedInstallationReturnsError,
mockUtils);
mockUtils,
mockIidStore);

// Expect exception
try {
Expand All @@ -485,7 +571,12 @@ public void testGetAuthToken_fidExists_successful() throws Exception {

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, mockPersistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
mockPersistedInstallation,
mockUtils,
mockIidStore);

InstallationTokenResult installationTokenResult =
Tasks.await(
Expand All @@ -506,7 +597,12 @@ public void testGetAuthToken_expiredAuthToken_fetchedNewTokenFromFIS() throws Ex

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

InstallationTokenResult installationTokenResult =
Tasks.await(
Expand All @@ -528,7 +624,12 @@ public void testGetAuthToken_unregisteredFid_fetchedNewTokenFromFIS() throws Exc

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

InstallationTokenResult installationTokenResult =
Tasks.await(
Expand All @@ -552,7 +653,12 @@ public void testGetAuthToken_serverError_failure() throws Exception {

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsError, mockPersistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsError,
mockPersistedInstallation,
mockUtils,
mockIidStore);

// Expect exception
try {
Expand Down Expand Up @@ -581,7 +687,12 @@ public void testGetAuthToken_multipleCallsDoNotForceRefresh_fetchedNewTokenOnce(

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

// Call getAuthToken multiple times with DO_NOT_FORCE_REFRESH option
Task<InstallationTokenResult> task1 =
Expand Down Expand Up @@ -632,7 +743,12 @@ public void testGetAuthToken_multipleCallsForceRefresh_fetchedNewTokenTwice() th

FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

// Call getAuthToken multiple times with FORCE_REFRESH option.
Task<InstallationTokenResult> task1 =
Expand Down Expand Up @@ -661,7 +777,12 @@ public void testDelete_registeredFID_successful() throws Exception {
persistedInstallation.insertOrUpdatePersistedInstallationEntry(REGISTERED_INSTALLATION_ENTRY);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

Tasks.await(firebaseInstallations.delete());

Expand All @@ -678,7 +799,12 @@ public void testDelete_unregisteredFID_successful() throws Exception {
persistedInstallation.insertOrUpdatePersistedInstallationEntry(UNREGISTERED_INSTALLATION_ENTRY);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

Tasks.await(firebaseInstallations.delete());

Expand All @@ -693,7 +819,12 @@ public void testDelete_unregisteredFID_successful() throws Exception {
public void testDelete_emptyPersistedFidEntry_successful() throws Exception {
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsOk, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsOk,
persistedInstallation,
mockUtils,
mockIidStore);

Tasks.await(firebaseInstallations.delete());

Expand All @@ -710,7 +841,12 @@ public void testDelete_serverError_failure() throws Exception {
persistedInstallation.insertOrUpdatePersistedInstallationEntry(REGISTERED_INSTALLATION_ENTRY);
FirebaseInstallations firebaseInstallations =
new FirebaseInstallations(
executor, firebaseApp, backendClientReturnsError, persistedInstallation, mockUtils);
executor,
firebaseApp,
backendClientReturnsError,
persistedInstallation,
mockUtils,
mockIidStore);

// Expect exception
try {
Expand Down
Loading