Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
Feiyang1 committed Jun 10, 2021
2 parents d200402 + 511ae26 commit 193633f
Showing 1 changed file with 17 additions and 36 deletions.
53 changes: 17 additions & 36 deletions packages/firestore/src/api/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import { Provider } from '@firebase/component';

import { User } from '../auth/user';
import { hardAssert, debugAssert } from '../util/assert';
import { debugAssert, hardAssert } from '../util/assert';
import { AsyncQueue } from '../util/async_queue';
import { Code, FirestoreError } from '../util/error';
import { logDebug } from '../util/log';
Expand Down Expand Up @@ -193,8 +193,8 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
/** Tracks the current User. */
private currentUser: User = User.UNAUTHENTICATED;

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

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

/** The listener registered with setChangeListener(). */
private changeListener: CredentialChangeListener = () => Promise.resolve();

private invokeChangeListener = false;
private changeListener?: CredentialChangeListener;

private forceRefresh = false;

Expand All @@ -217,18 +215,17 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
this.tokenListener = () => {
this.tokenCounter++;
this.currentUser = this.getUser();
this.receivedInitialUser.resolve();
if (this.invokeChangeListener) {
this.authDeferred.resolve();
if (this.changeListener) {
this.asyncQueue!.enqueueRetryable(() =>
this.changeListener(this.currentUser)
this.changeListener!(this.currentUser)
);
}
};

const registerAuth = (auth: FirebaseAuthInternal): void => {
logDebug('FirebaseCredentialsProvider', 'Auth detected');
this.auth = auth;
this.awaitTokenAndRaiseInitialEvent();
this.auth.addAuthTokenListener(this.tokenListener);
};

Expand All @@ -242,13 +239,10 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
const auth = authProvider.getImmediate({ optional: true });
if (auth) {
registerAuth(auth);
} else if (this.invokeChangeListener) {
// If auth is still not available, invoke the change listener once
// with null token
} else {
// If auth is still not available, proceed with `null` user
logDebug('FirebaseCredentialsProvider', 'Auth not yet detected');
this.asyncQueue!.enqueueRetryable(() =>
this.changeListener(this.currentUser)
);
this.authDeferred.resolve();
}
}
}, 0);
Expand Down Expand Up @@ -304,12 +298,14 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
changeListener: CredentialChangeListener
): void {
debugAssert(!this.asyncQueue, 'Can only call setChangeListener() once.');
this.invokeChangeListener = true;
this.asyncQueue = asyncQueue;
this.changeListener = changeListener;
if (this.auth) {
this.awaitTokenAndRaiseInitialEvent();
}

// Blocks the AsyncQueue until the next user is available.
this.asyncQueue!.enqueueRetryable(async () => {
await this.authDeferred.promise;
await changeListener(this.currentUser);
this.changeListener = changeListener;
});
}

removeChangeListener(): void {
Expand All @@ -331,21 +327,6 @@ export class FirebaseCredentialsProvider implements CredentialsProvider {
);
return new User(currentUid);
}

/**
* Blocks the AsyncQueue until the next user is available. This function also
* invokes `this.changeListener` immediately once the token is available.
*/
private awaitTokenAndRaiseInitialEvent(): void {
if (this.invokeChangeListener) {
this.invokeChangeListener = false; // Prevent double-firing of the listener
this.asyncQueue!.enqueueRetryable(async () => {
await this.receivedInitialUser.promise;
await this.changeListener(this.currentUser);
this.invokeChangeListener = true;
});
}
}
}

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

0 comments on commit 193633f

Please sign in to comment.