firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.86k stars 895 forks source link

onAuthStateChanged firing inconsistently on iPhone SE #5798

Open strid408 opened 2 years ago

strid408 commented 2 years ago

[REQUIRED] Describe your environment

--

[REQUIRED] Describe the problem

Steps to reproduce:

Users with iPhone SE have been getting stuck in a loading state upon loading our site in production. OnAuthStateChanged does not seem to fire consistently when loading the page. Users have to manually refresh their browser in order for onAuthStateChanged to fire.

I've created a minimal CRA project using firebase auth showcasing our problem. As far as we know, this behaviour only occurs on iPhone SE running iOS 14.6, regardless of browser (Chrome & Safari). We have not had any problems with other iOS or android devices.

Relevant Code:

import { getAuth, signInAnonymously, onAuthStateChanged } from "firebase/auth";
import { useState } from "react";
import { initializeApp } from "@firebase/app";

const firebaseConfig = {
 ...
};

const firebaseApp = initializeApp(firebaseConfig);

const auth = getAuth(firebaseApp);

function App() {
  const [currentUser, setCurrentUser] = useState(null);
  const [loading, setLoading] = useState(true);

  onAuthStateChanged(auth, (user) => {
    if (user) {
      setCurrentUser(user.uid);
    } else {
      setCurrentUser(null);
    }
    setLoading(false);
  });

  if (loading) {
    return <p>LOADING</p>;
  }

  if (currentUser) {
    return (
      <p>
        Welcome {currentUser}!
        <button
          onClick={() => {
            auth.signOut();
          }}
        >
          Sign out
        </button>
      </p>
    );
  } else {
    return (
      <div>
        <button onClick={() => signInAnonymously(auth)}>Login</button>
      </div>
    );
  }
}

export default App;
weixifan commented 2 years ago

I filed an internal b/212487679 to track. Thank you for reporting this.

JumBay commented 2 years ago

I do encounter a similar issue. I use @angular/fire (^7.2.0 with firebase ^9.6.2) on an ionic + capacitor project and onAuthStateChanged never fires on iOS devices. Tested on iPhone 13 (simulator) and iPhone 6s (real device). Edit: found a workaround here https://github.com/firebase/firebase-js-sdk/issues/5019

pascallalonde commented 2 years ago

I am randomly experiencing the same behavior in a Webworker on Safari. On some loads, the auth will be resolved, but in others it won't and hang forever. @angular/fire@7.2.1 and firebase@9.6.6

This is how I manage the auth:


    const app = initializeApp(this.environment.firebase);
    const auth = initializeAuth(app, { persistence: indexedDBLocalPersistence });

[...]

    console.log(`Awaiting firebase auth.`);
    return new Promise((resolve) => {
      let timeBomb: any = 0;
      const cb = auth.onAuthStateChanged(
        (user) => {
          if (user) {
            clearTimeout(timeBomb);
            resolve();
            cb();
          }
        },
        (err) => {
          resolve();
          console.error(`An error occurred while looking for auth state change events. [${err}]`);
        }
      );

      timeBomb = setTimeout(() => {
        console.log(`WAITED FOR TO LONG TO GET AUTH. :(((`);
        cb();
        resolve();
      }, 1000);
    });

What's weird about it is that, since I am resolving anyway after the timeout, some of the subsequent calls to the firebase sdk will work anyway.

[EDIT] It seems that when it happens, the saved token is no longer in IndexedDb store. When looking in firebaseLocalStorageDb/firebaseLocalStorage, it's empty.

mcarriere commented 2 years ago

We encounter the same issue on regular desktop Safari and multiple iOS devices using Capacitor, onAuthStateChanged works inconsistently. This is an issue for us because we spawn multiple web workers and we need to setup the auth for each of them.

gugahoi commented 2 years ago

Has anyone been able to find anything related? I observer something similar in Capacitor + iOS as well.

skndash96 commented 1 year ago

The same scenario happened to me. What I did was, await setPersistence(auth, browserLocalPersistence); and everything seemed to work fine including the persistence of user and triggering of authStateChange event. Hope that helps!

wooliet commented 1 year ago

Just ran into something similar using firebase web sdk v10.x running in our Capacitor based app on ios. Only had an issue on the native ios builds. Worked fine on macos/windows browsers (including Safari) and Android.

Was using the getAuth(app) version of initialization, followed closely by a call to the async setPersistence(auth, browserLocalPersistence).

The call to setPersistence would never resolve. What's more, elsewhere in code, onAuthStateChanged would never fire.

Changed init code to only the below (removed call to setPersistence), and auth started working again.

initializeAuth(app, {
  persistence: browserLocalPersistence
});
rmertens commented 10 months ago

We also encountered this on iPad:

Safari 17.1.1 on Mac OS (iPad)

Is there any news?

dlarocque commented 3 months ago

It seems like a lot of people are having issues with this, but I can't seem to get a reproduction of the issue on MacOS Safari. I have created an Ionic Capacitor app that has web workers that perform sign in, and listen for changes with onAuthStateChanged- but this seems to work correctly on Safari 17.

Could anyone who's been seeing issues with Capacitor share more info that would help me reproduce the bug? @gugahoi @mcarriere