pelak
pelak

Reputation: 68

React Native Firebase undefined is not an object (evaluating 'this.storage.setItem')

It's my first time using firebase and I'm trying to set the persistence but getting an error. I'm using expo on react native. Here's my code:

import firebase from "firebase/compat/app";
import "firebase/compat/auth";
import "firebase/compat/firestore";

const confirmCode = async () => {
        const credential = firebase.auth.PhoneAuthProvider.credential(
          verificationId,
          code
        );
    
        firebase
          .auth()
          .setPersistence(firebase.auth.Auth.Persistence.LOCAL)
          .then(async () => {
            return firebase
              .auth()
              .signInWithCredential(credential)
              .then((result) => {
                setIsNew(result.additionalUserInfo.isNewUser);
                result.user.getIdToken().then((token) => setUserToken(token));
              });
          })
          .catch((error) => {
            console.log(error.message);
          });
      };

I'm getting error undefined is not an object (evaluating 'this.storage.setItem') when it comes to persisting.

I'm using this page in google docs and newest version of firebase 9.6.8. It's working fine without persistance but then user have to log in everytime he opens an app.

I've searched dozens of threads on stackoverflow and github but I haven't found any answer for that problem.

And also this isn't showing any user logged in with or without persisting:

if (firebase.auth().currentUser !== null) {
    console.log(firebase.auth().currentUser.uid);
  } else {
    console.log("no users logged");
  }

I thought about somehow using async storage but I don't really know how I could make it work.

Upvotes: 1

Views: 2221

Answers (3)

Umair A.
Umair A.

Reputation: 6873

This is what worked for me in Feb 2024.

import firebase from 'firebase/compat/app';
import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
import AsyncStorage from '@react-native-async-storage/async-storage';

import "firebase/compat/auth";
// import "firebase/compat/firestore";
// import "firebase/compat/functions";
// import "firebase/compat/storage";

import firebaseConfig from '../firebase';

if (!firebase.apps.length) {
    const defaultApp = firebase.initializeApp(firebaseConfig);
    initializeAuth(defaultApp, {
        persistence: getReactNativePersistence(AsyncStorage)
    });
}

Upvotes: 0

pelak
pelak

Reputation: 68

If anyone has the same problem - I managed to solve it with help from Bernard Allotey. Here is how I did it:

In App.js:

    import { initializeApp } from "firebase/app";
    import { initializeAuth } from "firebase/auth";
    import { getReactNativePersistence } from "firebase/auth/react-native";
    import AsyncStorage from "@react-native-async-storage/async-storage";
    import firebaseConfig from "./firebaseConfing";
    
    useEffect(async () => {
        const defaultApp = initializeApp(firebaseConfig);
        initializeAuth(defaultApp, {
          persistence: getReactNativePersistence(AsyncStorage),
        });

     }, []);

In my very first screen:

import { getAuth, onAuthStateChanged } from "firebase/auth";

onAuthStateChanged(getAuth(), (user) => {
    if (user) {
      console.log(user);
    } else {
      console.log("signed out");
    }
  });

And for login I'm using this:

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    async function sendVerification() {
        const auth = getAuth();
        signInWithPhoneNumber(
          auth,
          countryCode + phoneNumber,
          recaptchaVerifier.current
        ).then((confirmationResult) =>
          navigation.navigate("SmsCode", {
            confirmationResult: confirmationResult,
            phoneNumber: phoneNumber,
          })
        );
      }
    
// next screen

    const confirmCode = async () => {
        confirmationResult.confirm(code).then((result) => {
          result.user.getIdToken().then(async (token) => {
            setUserToken(token);
          });
        });
      };

Now the user is persisting as I wanted. Huge thanks for help.

Upvotes: 2

Bernard Allotey
Bernard Allotey

Reputation: 822

Ok, so I realized that to preserve login state, you actually have to do a special process if using expo. You need to initialize your own auth, passing in Async Storage, like so. When doing it this way, there is no need to set persistence.

import { initializeApp } from "firebase/app"
import { initializeAuth } from "firebase/auth"
import { getReactNativePersistence } from "firebase/auth/react-native"
import AsyncStorage from "@react-native-async-storage/async-storage"

const defaultApp = initializeApp(config);
initializeAuth(defaultApp, {
  persistence: getReactNativePersistence(AsyncStorage)
});

Upvotes: 0

Related Questions