Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onAuthStateChange called on first user token refresh and it should not happen #5685

Closed
acanimal opened this issue Oct 29, 2021 · 0 comments · Fixed by #5686
Closed

onAuthStateChange called on first user token refresh and it should not happen #5685

acanimal opened this issue Oct 29, 2021 · 0 comments · Fixed by #5686

Comments

@acanimal
Copy link

Hi,
I started as a tech question in stackoverflow but it seems it is a bug

[REQUIRED] Describe your environment

  • Operating System version: macosx
  • Browser version: chrome 95
  • Firebase SDK version: 9.2.0, 9.1.3
  • Firebase Product: auth

[REQUIRED] Describe the problem

As doc explains onAuthStateChange should be called only on signin and signout actions. It seems the listener is also called on the first user token refresh.

Steps to reproduce:

<html>
  <script src="https://www.gstatic.com/firebasejs/9.1.3/firebase-app-compat.js"></script>
  <script src="https://www.gstatic.com/firebasejs/9.1.3/firebase-auth-compat.js"></script>
  <script>
    // Initialize Firebase
    const config = {
      apiKey: '',
      authDomain: '',
      databaseURL: '',
      projectId: '',
      storageBucket: '',
      messagingSenderId: '',
      appId: '',
    };
    const email = "mail12345@mail.com";
    const pass = "123456abc";
    const app = firebase.initializeApp(config);
    const auth = app.auth();

    const example = async () => {
      auth.onAuthStateChanged(async (user) => {
        console.log('onAuthStateChanged user uid', user ? user.uid : 'null');

        if (!user) {
          try {
            await auth.createUserWithEmailAndPassword(email, pass);
          } catch (e) {
            console.log('user already created');
          }

          console.log('signin')
          await auth.signInWithEmailAndPassword(email, pass);
        }
      })

      setInterval(() => {
        console.log('force token renewal');
        auth.currentUser.getIdToken(true);
      }, 5000)
    };

    example();
  </script>
</html>

The output

If you run for the first time or if there is no session you get the output:

onAuthStateChanged user uid null   <-- becuase there is no session stored
user already created
signin
onAuthStateChanged user uid mqLHdtQhwJPaXqIEbDqFBwFoxLz1 <-- this is because the signin
force token renewal <-- run each 5 secs

Having a session stored if you refresh the page you find the next output:

onAuthStateChanged user uid mqLHdtQhwJPaXqIEbDqFBwFoxLz1 <-- recover the session
force token renewal
onAuthStateChanged user uid mqLHdtQhwJPaXqIEbDqFBwFoxLz1 <-- run again after refresh token
force token renewal <-- subsequent refresh token doesn not cause a call to onAuthStateChange

The problem is with the first refresh of token. After debugging a bit in chrome I found that on the first token refresh the function notifyAuthListeners() from the file auth_impl.ts is invoked but the variable this.lastNotifiedUid is undefined which causes the refresh to be notified also to onAuthStateChange listeners.

@jbalidiong jbalidiong added the v9 label Oct 29, 2021
@sam-gc sam-gc added the bug label Oct 29, 2021
@firebase firebase locked and limited conversation to collaborators Nov 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
4 participants