Skip to content

Commit 5b0acbf

Browse files
authored
FID delete() implementation. (#813)
* FID delete() implementation. * Addressing ciaran's comments. * Refractoring the code to be inline.
1 parent 6a013fa commit 5b0acbf

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

firebase-installations/src/androidTest/java/com/google/firebase/installations/FirebaseInstallationsInstrumentedTest.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
import static org.mockito.ArgumentMatchers.any;
3333
import static org.mockito.ArgumentMatchers.anyString;
3434
import static org.mockito.Mockito.doAnswer;
35+
import static org.mockito.Mockito.doNothing;
36+
import static org.mockito.Mockito.doThrow;
37+
import static org.mockito.Mockito.never;
3538
import static org.mockito.Mockito.times;
3639
import static org.mockito.Mockito.verify;
3740
import static org.mockito.Mockito.when;
@@ -163,6 +166,16 @@ public void setUp() throws FirebaseInstallationServiceException {
163166
when(persistedFidReturnsError.readPersistedFidEntryValue()).thenReturn(null);
164167
when(mockUtils.createRandomFid()).thenReturn(TEST_FID_1);
165168
when(mockClock.currentTimeMillis()).thenReturn(TEST_CREATION_TIMESTAMP_1);
169+
// Mocks success on FIS deletion
170+
doNothing()
171+
.when(backendClientReturnsOk)
172+
.deleteFirebaseInstallation(anyString(), anyString(), anyString(), anyString());
173+
// Mocks server error on FIS deletion
174+
doThrow(
175+
new FirebaseInstallationServiceException(
176+
"Server Error", FirebaseInstallationServiceException.Status.SERVER_ERROR))
177+
.when(backendClientReturnsError)
178+
.deleteFirebaseInstallation(anyString(), anyString(), anyString(), anyString());
166179
}
167180

168181
@After
@@ -483,4 +496,77 @@ public void testGetAuthToken_multipleCallsForceRefresh_fetchedNewTokenTwice() th
483496
verify(backendClientReturnsOk, times(2))
484497
.generateAuthToken(TEST_API_KEY, TEST_FID_1, TEST_PROJECT_ID, TEST_REFRESH_TOKEN);
485498
}
499+
500+
@Test
501+
public void testDelete_registeredFID_successful() throws Exception {
502+
// Update local storage with a registered fid entry
503+
persistedFid.insertOrUpdatePersistedFidEntry(REGISTERED_FID_ENTRY);
504+
FirebaseInstallations firebaseInstallations =
505+
new FirebaseInstallations(
506+
mockClock, executor, firebaseApp, backendClientReturnsOk, persistedFid, mockUtils);
507+
508+
Tasks.await(firebaseInstallations.delete());
509+
510+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
511+
assertWithMessage("Persisted Fid Entry is not null.").that(entryValue).isNull();
512+
verify(backendClientReturnsOk, times(1))
513+
.deleteFirebaseInstallation(TEST_API_KEY, TEST_FID_1, TEST_PROJECT_ID, TEST_REFRESH_TOKEN);
514+
}
515+
516+
@Test
517+
public void testDelete_unregisteredFID_successful() throws Exception {
518+
// Update local storage with a unregistered fid entry
519+
persistedFid.insertOrUpdatePersistedFidEntry(UNREGISTERED_FID_ENTRY);
520+
FirebaseInstallations firebaseInstallations =
521+
new FirebaseInstallations(
522+
mockClock, executor, firebaseApp, backendClientReturnsOk, persistedFid, mockUtils);
523+
524+
Tasks.await(firebaseInstallations.delete());
525+
526+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
527+
assertWithMessage("Persisted Fid Entry is not null.").that(entryValue).isNull();
528+
verify(backendClientReturnsOk, never())
529+
.deleteFirebaseInstallation(TEST_API_KEY, TEST_FID_1, TEST_PROJECT_ID, TEST_REFRESH_TOKEN);
530+
}
531+
532+
@Test
533+
public void testDelete_emptyPersistedFidEntry_successful() throws Exception {
534+
FirebaseInstallations firebaseInstallations =
535+
new FirebaseInstallations(
536+
mockClock, executor, firebaseApp, backendClientReturnsOk, persistedFid, mockUtils);
537+
538+
Tasks.await(firebaseInstallations.delete());
539+
540+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
541+
assertWithMessage("Persisted Fid Entry is not null.").that(entryValue).isNull();
542+
verify(backendClientReturnsOk, never())
543+
.deleteFirebaseInstallation(TEST_API_KEY, TEST_FID_1, TEST_PROJECT_ID, TEST_REFRESH_TOKEN);
544+
}
545+
546+
@Test
547+
public void testDelete_serverError_failure() throws Exception {
548+
// Update local storage with a registered fid entry
549+
persistedFid.insertOrUpdatePersistedFidEntry(REGISTERED_FID_ENTRY);
550+
FirebaseInstallations firebaseInstallations =
551+
new FirebaseInstallations(
552+
mockClock, executor, firebaseApp, backendClientReturnsError, persistedFid, mockUtils);
553+
554+
// Expect exception
555+
try {
556+
Tasks.await(firebaseInstallations.delete());
557+
fail("delete() failed due to Server Error.");
558+
} catch (ExecutionException expected) {
559+
assertWithMessage("Exception class doesn't match")
560+
.that(expected)
561+
.hasCauseThat()
562+
.isInstanceOf(FirebaseInstallationsException.class);
563+
assertWithMessage("Exception status doesn't match")
564+
.that(((FirebaseInstallationsException) expected.getCause()).getStatus())
565+
.isEqualTo(FirebaseInstallationsException.Status.SDK_INTERNAL_ERROR);
566+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
567+
assertWithMessage("Persisted Fid Entry doesn't match")
568+
.that(entryValue)
569+
.isEqualTo(REGISTERED_FID_ENTRY);
570+
}
571+
}
486572
}

firebase-installations/src/main/java/com/google/firebase/installations/FirebaseInstallations.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public synchronized Task<InstallationTokenResult> getAuthToken(
156156
@NonNull
157157
@Override
158158
public Task<Void> delete() {
159-
return Tasks.forResult(null);
159+
return Tasks.call(executor, this::deleteFirebaseInstallationId);
160160
}
161161

162162
/** Returns the application id of the {@link FirebaseApp} of this {@link FirebaseInstallations} */
@@ -400,6 +400,34 @@ private boolean isAuthTokenExpired(PersistedFidEntry persistedFidEntry) {
400400
private long currentTimeInSecs() {
401401
return TimeUnit.MILLISECONDS.toSeconds(clock.currentTimeMillis());
402402
}
403+
404+
/**
405+
* Deletes the firebase installation id of the {@link FirebaseApp} from FIS servers and local
406+
* storage.
407+
*/
408+
private Void deleteFirebaseInstallationId() throws FirebaseInstallationsException {
409+
410+
PersistedFidEntry persistedFidEntry = persistedFid.readPersistedFidEntryValue();
411+
412+
if (isPersistedFidRegistered(persistedFidEntry)) {
413+
// Call the FIS servers to delete this firebase installation id.
414+
try {
415+
serviceClient.deleteFirebaseInstallation(
416+
firebaseApp.getOptions().getApiKey(),
417+
persistedFidEntry.getFirebaseInstallationId(),
418+
firebaseApp.getOptions().getProjectId(),
419+
persistedFidEntry.getRefreshToken());
420+
421+
} catch (FirebaseInstallationServiceException exception) {
422+
throw new FirebaseInstallationsException(
423+
"Failed to delete a Firebase Installation.",
424+
FirebaseInstallationsException.Status.SDK_INTERNAL_ERROR);
425+
}
426+
}
427+
428+
persistedFid.clear();
429+
return null;
430+
}
403431
}
404432

405433
interface Supplier<T> {

0 commit comments

Comments
 (0)