firebase-js-sdk icon indicating copy to clipboard operation
firebase-js-sdk copied to clipboard

onAuthStateChanged firing inconsistently on iPhone SE

Open strid408 opened this issue 3 years ago • 9 comments

[REQUIRED] Describe your environment

  • Operating System version: iOS 14.6
  • Browser version: Safari 14.6 / Chrome 96.0.4664.53
  • Firebase SDK version: 9.6
  • Firebase Product: auth

--

  • Device: iPhone SE
  • React version: 17.0.2
  • React environment: Create-react-app

[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;

strid408 avatar Dec 07 '21 12:12 strid408

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

weixifan avatar Dec 29 '21 12:12 weixifan

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

JumBay avatar Jan 10 '22 13:01 JumBay

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/[email protected] and [email protected]

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.

pascallalonde avatar Feb 24 '22 14:02 pascallalonde

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.

mcarriere avatar Feb 24 '22 14:02 mcarriere

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

gugahoi avatar Jul 05 '22 07:07 gugahoi

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!

skndash96 avatar Jan 23 '23 13:01 skndash96

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
});

wooliet avatar Nov 01 '23 19:11 wooliet

We also encountered this on iPad:

Safari 17.1.1 on Mac OS (iPad)

Is there any news?

rmertens avatar Jan 18 '24 18:01 rmertens