Is there a way to persist Firebase Auth state in capacitor?

Viewed 723

I'm developing a Ionic/React/Capacitor app.

I'm calling firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL) when the app starts.

Everything works fine in the browser. But when deployed, the auth state isn't persisted when I restart the app. I first thought Capacitor might not support IndexedDB/Local Storage but even after installing Microsoft's IndexedDB Cordova plugin, it still doesn't work (I'm assuming that plugin is compatible with capacitor).

Is there any way to get this working or will I have to persist the auth state myself?

2 Answers

at startup you need to check if there is an existing authenticated user...

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    var displayName = user.displayName;
    var email = user.email;
    var emailVerified = user.emailVerified;
    var photoURL = user.photoURL;
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
    var providerData = user.providerData;
    // ...
  } else {
    // User is signed out.
    // ...
  }
});

https://firebase.google.com/docs/auth/web/start

I faced a similar issue - there can be a few reasons as to why the authentication state isn't persisted - but most probably it's because the Firebase SDK cannot refresh your idToken using the refreshToken.

  1. Check the permissions for the API key by going to the Google Cloud console. The API key needs permission to use the Token Service API along with the Identity Toolkit API to refresh the "idToken" by using the "refreshToken".

  2. Setting the Persistence to "LOCAL" won't fix the problem because it is "LOCAL" by default.

  3. The Firebase JS SDK uses IndexedDB to store the Refresh key (which has a validity of 1 year). If IndexedDB is not available, it will use LocalStorage. As per Capacitor's docs, both IndexedDB and LocalStorage are cleared by the operating system (Android or iOS) if the device is running low on space. I assume this is pretty rare since users are not being logged out on my apps.

  4. If you want to remove the dependency on IndexedDB or LocalStorage, you could also store the refresh token (obtained while logging in) in secure persistent storage using a Capacitor plugin, and then use that token to request a new idToken using Firebase's Authentication REST API. You would then have to use the onIdTokenChanged listener to keep a track of authentication state. see here

Related