Firebase Auth on Expo expiring authentication after a couple of hours

Viewed 1329

I have an Expo app, using AppAuth to authenticate with Google. After user is authenticated with Google I build the Firebase Credentials with the Google ID token and sign them in with Firebase.

Authentication and reads to Firebase work well, after a couple of hours when the user comes back, the user is no longer authenticated with Firebase.

PS: refreshing or closing the app keeps the user authenticated, it seems to be a timely thing.

Persistence should be on by default, according to the documentations, but I've also tried forcing it by using .setPersistence(firebase.auth.Auth.Persistence.LOCAL), no success.

Here is my code:

  onSignIn = googleUser => {
    // We need to register an Observer on Firebase Auth to make sure auth is initialized.
    var unsubscribe = firebase.auth().onAuthStateChanged(
      function(firebaseUser) {
        unsubscribe();

        firebase
          .auth()
          .setPersistence(firebase.auth.Auth.Persistence.LOCAL)
          .then(() => {
            // Check if we are already signed-in Firebase with the correct user.
            if (!this.isUserEqual(googleUser, firebaseUser)) {
              // Build Firebase credential with the Google ID token.
              var credential = firebase.auth.GoogleAuthProvider.credential(
                googleUser.idToken,
                googleUser.accessToken
              );
              // Sign in with credential from the Google user.
              firebase
                .auth()
                .signInWithCredential(credential)
                .then(function(result) {
                  if (result.additionalUserInfo.isNewUser) {
                    firebase
                      .firestore()
                      .collection("users")
                      .doc(result.user.email)
                      .set({
                        email: result.user.email,
                        profile_picture:
                          result.additionalUserInfo.profile.picture,
                        first_name:
                          result.additionalUserInfo.profile.given_name,
                        last_name:
                          result.additionalUserInfo.profile.family_name,
                        full_name: result.additionalUserInfo.profile.name,
                        locale: result.additionalUserInfo.profile.locale,
                        provider_id: result.additionalUserInfo.providerId,
                        created_at: Date.now()
                      })
                      .then(function(snapshot) {});
                  } else {
                    firebase
                      .firestore()
                      .collection("users")
                      .doc(result.user.email)
                      .update({
                        last_logged_in: Date.now()
                      });
                  }
                })
                .catch(function(error) {
                  console.log(error);
                  // Handle Errors here.
                  var errorCode = error.code;
                  var errorMessage = error.message;
                  // The email of the user's account used.
                  var email = error.email;
                  // The firebase.auth.AuthCredential type that was used.
                  var credential = error.credential;
                });
          } else {
              console.log("User already signed-in Firebase.");
            }
          });
      }.bind(this)
    );
  };

signInAsync = async () => {
    const authState = await AppAuth.authAsync(config);
    await this.cacheAuthAsync(authState);
    this.onSignIn(authState);
    return authState;
  };

I'm expecting the session and authentication to be open and be refreshed automatically.

2 Answers

Edit

According to this: When to set Firebase auth state persistence, it shouldn't matter

Original Answer

I think you might have to setPersistence before onAuthStateChanged

onSignIn = googleUser => {
  return firebase.auth().setPersistence()
      .then(() => {
          return new Promise((resolve, reject) => {
              const unsubscribe = firebase.auth().onAuthStateChange((result) => {
                   resolve(result)
          })
      })
      .then( /// etc
}
Related