diff --git a/.changeset/happy-eels-confess.md b/.changeset/happy-eels-confess.md new file mode 100644 index 00000000000..78233e52017 --- /dev/null +++ b/.changeset/happy-eels-confess.md @@ -0,0 +1,5 @@ +--- +"@firebase/auth": patch +--- + +Fix proactive refresh logic in Auth when RTDB/Firestore/Storage are in use diff --git a/packages/auth/src/core/auth/auth_impl.test.ts b/packages/auth/src/core/auth/auth_impl.test.ts index 0ac1f793f7f..6167de7b62b 100644 --- a/packages/auth/src/core/auth/auth_impl.test.ts +++ b/packages/auth/src/core/auth/auth_impl.test.ts @@ -306,6 +306,65 @@ describe('core/auth/auth_impl', () => { }); }); + context('with Proactive Refresh', () => { + let oldUser: UserInternal; + + beforeEach(() => { + oldUser = testUser(auth, 'old-user-uid'); + + for (const u of [user, oldUser]) { + sinon.spy(u, '_startProactiveRefresh'); + sinon.spy(u, '_stopProactiveRefresh'); + } + }); + + it('null -> user: does not turn on if not enabled', async () => { + await auth._updateCurrentUser(null); + await auth._updateCurrentUser(user); + + expect(user._startProactiveRefresh).not.to.have.been.called; + }); + + it('null -> user: turns on if enabled', async () => { + await auth._updateCurrentUser(null); + auth._startProactiveRefresh(); + await auth._updateCurrentUser(user); + + expect(user._startProactiveRefresh).to.have.been.called; + }); + + it('user -> user: does not turn on if not enabled', async () => { + await auth._updateCurrentUser(oldUser); + await auth._updateCurrentUser(user); + + expect(user._startProactiveRefresh).not.to.have.been.called; + }); + + it('user -> user: turns on if enabled', async () => { + auth._startProactiveRefresh(); + await auth._updateCurrentUser(oldUser); + await auth._updateCurrentUser(user); + + expect(oldUser._stopProactiveRefresh).to.have.been.called; + expect(user._startProactiveRefresh).to.have.been.called; + }); + + it('calling start on auth triggers user to start', async () => { + await auth._updateCurrentUser(user); + auth._startProactiveRefresh(); + + expect(user._startProactiveRefresh).to.have.been.calledOnce; + }); + + it('calling stop stops the refresh on the current user', async () => { + auth._startProactiveRefresh(); + await auth._updateCurrentUser(user); + auth._stopProactiveRefresh(); + + expect(user._stopProactiveRefresh).to.have.been.called; + }); + }); + it('onAuthStateChange works for multiple listeners', async () => { const cb1 = sinon.spy(); const cb2 = sinon.spy(); diff --git a/packages/auth/src/core/auth/auth_impl.ts b/packages/auth/src/core/auth/auth_impl.ts index 3f306530c7b..92467933da7 100644 --- a/packages/auth/src/core/auth/auth_impl.ts +++ b/packages/auth/src/core/auth/auth_impl.ts @@ -581,9 +581,9 @@ export class AuthImpl implements AuthInternal, _FirebaseService { ): Promise { if (this.currentUser && this.currentUser !== user) { this._currentUser._stopProactiveRefresh(); - if (user && this.isProactiveRefreshEnabled) { - user._startProactiveRefresh(); - } + } + if (user && this.isProactiveRefreshEnabled) { + user._startProactiveRefresh(); } this.currentUser = user;