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 5109523815b..b095ffc0b7a 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 @@ -143,12 +143,8 @@ public Task getId() { */ @NonNull @Override - public synchronized Task getAuthToken( - @AuthTokenOption int authTokenOption) { - if (authTokenOption == FORCE_REFRESH) { - shouldRefreshAuthToken = true; - } - Task task = addGetAuthTokenListener(); + public Task getAuthToken(@AuthTokenOption int authTokenOption) { + Task task = addGetAuthTokenListener(authTokenOption); executor.execute(doRegistration()); return task; } @@ -173,12 +169,13 @@ private Task addGetIdListener() { return taskCompletionSource.getTask(); } - private Task addGetAuthTokenListener() { - TaskCompletionSource taskCompletionSource = - new TaskCompletionSource<>(); - StateListener l = new GetAuthTokenListener(utils, taskCompletionSource); + private Task addGetAuthTokenListener(@AuthTokenOption int authTokenOption) { + TaskCompletionSource taskCompletionSource = new TaskCompletionSource<>(); synchronized (lock) { - listeners.add(l); + if (authTokenOption == FORCE_REFRESH) { + desiredRevisionId = currentRevisionId + 1; + } + listeners.add(new GetAuthTokenListener(utils, taskCompletionSource, desiredRevisionId);); } return taskCompletionSource.getTask(); } @@ -188,7 +185,8 @@ private void triggerOnStateReached(PersistedFidEntry persistedFidEntry) { Iterator it = listeners.iterator(); while (it.hasNext()) { StateListener l = it.next(); - boolean doneListening = l.onStateReached(persistedFidEntry); + // TODO(ankitaj224): add this param to the `onStateReached` interface method + boolean doneListening = l.onStateReached(currentRevisionId, persistedFidEntry); if (doneListening) { it.remove(); } @@ -208,25 +206,36 @@ private final Runnable doRegistration() { persistedFidEntry = persistedFid.readPersistedFidEntryValue(); } - // If Auth Token needs refresh, notify the listeners only after force refresh - if (!shouldRefreshAuthToken) { - triggerOnStateReached(persistedFidEntry); - } + triggerOnStateReached(persistedFidEntry); // FID needs to be registered if (persistedFidEntry.isUnregistered()) { registerAndSaveFid(persistedFidEntry); persistedFidEntry = persistedFid.readPersistedFidEntryValue(); + // we just registered, so any requests that were waiting on a fresher token will be satisfied, no refresh required + synchronized (lock) { + currentRevisionId = desiredRevisionId; + } } // Don't notify the listeners at this point; we might as well make ure the auth token is up // to date before letting them know. + boolean needRefresh = utils.isAuthTokenExpired(persistedFidEntry); + if (!needRefresh) { + synchronized (lock) { + needRefresh = desiredRevisionId > currentRevisionId; + } + } + // Refresh Auth token if needed - if (shouldRefreshAuthToken || utils.isAuthTokenExpired(persistedFidEntry)) { - shouldRefreshAuthToken = false; + if (needRefresh) { fetchAuthTokenFromServer(persistedFidEntry); persistedFidEntry = persistedFid.readPersistedFidEntryValue(); + + synchronized (lock) { + currentRevisionId = desiredRevisionId; + } } triggerOnStateReached(persistedFidEntry);