Skip to content

Commit 511ae26

Browse files
Block on Auth synchronously (#5008)
1 parent 4c4b6ae commit 511ae26

File tree

1 file changed

+17
-36
lines changed

1 file changed

+17
-36
lines changed

packages/firestore/src/api/credentials.ts

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
import { Provider } from '@firebase/component';
2323

2424
import { User } from '../auth/user';
25-
import { hardAssert, debugAssert } from '../util/assert';
25+
import { debugAssert, hardAssert } from '../util/assert';
2626
import { AsyncQueue } from '../util/async_queue';
2727
import { Code, FirestoreError } from '../util/error';
2828
import { logDebug } from '../util/log';
@@ -193,8 +193,8 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
193193
/** Tracks the current User. */
194194
private currentUser: User = User.UNAUTHENTICATED;
195195

196-
/** Promise that allows blocking on the first `tokenListener` event. */
197-
private receivedInitialUser = new Deferred();
196+
/** Promise that allows blocking on the initialization of Firebase Auth. */
197+
private authDeferred = new Deferred();
198198

199199
/**
200200
* Counter used to detect if the token changed while a getToken request was
@@ -203,9 +203,7 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
203203
private tokenCounter = 0;
204204

205205
/** The listener registered with setChangeListener(). */
206-
private changeListener: CredentialChangeListener = () => Promise.resolve();
207-
208-
private invokeChangeListener = false;
206+
private changeListener?: CredentialChangeListener;
209207

210208
private forceRefresh = false;
211209

@@ -217,18 +215,17 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
217215
this.tokenListener = () => {
218216
this.tokenCounter++;
219217
this.currentUser = this.getUser();
220-
this.receivedInitialUser.resolve();
221-
if (this.invokeChangeListener) {
218+
this.authDeferred.resolve();
219+
if (this.changeListener) {
222220
this.asyncQueue!.enqueueRetryable(() =>
223-
this.changeListener(this.currentUser)
221+
this.changeListener!(this.currentUser)
224222
);
225223
}
226224
};
227225

228226
const registerAuth = (auth: FirebaseAuthInternal): void => {
229227
logDebug('FirebaseCredentialsProvider', 'Auth detected');
230228
this.auth = auth;
231-
this.awaitTokenAndRaiseInitialEvent();
232229
this.auth.addAuthTokenListener(this.tokenListener);
233230
};
234231

@@ -242,13 +239,10 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
242239
const auth = authProvider.getImmediate({ optional: true });
243240
if (auth) {
244241
registerAuth(auth);
245-
} else if (this.invokeChangeListener) {
246-
// If auth is still not available, invoke the change listener once
247-
// with null token
242+
} else {
243+
// If auth is still not available, proceed with `null` user
248244
logDebug('FirebaseCredentialsProvider', 'Auth not yet detected');
249-
this.asyncQueue!.enqueueRetryable(() =>
250-
this.changeListener(this.currentUser)
251-
);
245+
this.authDeferred.resolve();
252246
}
253247
}
254248
}, 0);
@@ -304,12 +298,14 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
304298
changeListener: CredentialChangeListener
305299
): void {
306300
debugAssert(!this.asyncQueue, 'Can only call setChangeListener() once.');
307-
this.invokeChangeListener = true;
308301
this.asyncQueue = asyncQueue;
309-
this.changeListener = changeListener;
310-
if (this.auth) {
311-
this.awaitTokenAndRaiseInitialEvent();
312-
}
302+
303+
// Blocks the AsyncQueue until the next user is available.
304+
this.asyncQueue!.enqueueRetryable(async () => {
305+
await this.authDeferred.promise;
306+
await changeListener(this.currentUser);
307+
this.changeListener = changeListener;
308+
});
313309
}
314310

315311
removeChangeListener(): void {
@@ -331,21 +327,6 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
331327
);
332328
return new User(currentUid);
333329
}
334-
335-
/**
336-
* Blocks the AsyncQueue until the next user is available. This function also
337-
* invokes `this.changeListener` immediately once the token is available.
338-
*/
339-
private awaitTokenAndRaiseInitialEvent(): void {
340-
if (this.invokeChangeListener) {
341-
this.invokeChangeListener = false; // Prevent double-firing of the listener
342-
this.asyncQueue!.enqueueRetryable(async () => {
343-
await this.receivedInitialUser.promise;
344-
await this.changeListener(this.currentUser);
345-
this.invokeChangeListener = true;
346-
});
347-
}
348-
}
349330
}
350331

351332
// Manual type definition for the subset of Gapi we use.

0 commit comments

Comments
 (0)