skip to Main Content

I’m having an issue with implementing SMS authentication through Firebase. I’ve been trying to study the documentation and use Google to find a solution, but so far without success. I have a simple page with one input field and a "Send" button. I’m developing an Android app using Expo.

However, when trying to initialize Firebase Auth for React Native, Expo gives me the following error:

WARN [2023-09-05T05:59:10.503Z] @firebase/auth: Auth (10.3.1):
You are initializing Firebase Auth for React Native without providing AsyncStorage. Auth state will default to memory persistence and will not persist between sessions. In order to persist auth state, install the package "@react-native-async-storage/async-storage" and provide it to initializeAuth:

import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';
const auth = initializeAuth(app, {
  persistence: getReactNativePersistence(ReactNativeAsyncStorage)
});

Could you please explain how I can solve this issue? I’ve already installed the package "@react-native-async-storage/async-storage", but I don’t understand how to properly use it to initialize Firebase Auth.

Thank you in advance for your help!

  import React, { useState } from "react";
    import { Alert, Button, StyleSheet, TextInput, View } from "react-native";
    import { initializeApp } from "firebase/app";
    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    import AsyncStorage from "@react-native-async-storage/async-storage";
    import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
    import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';

    const firebaseConfig = {
      apiKey: "AIzaSyD5Qg_t9KR4TmLr2p14E2aODO9UV5RehUE",
      authDomain: "sharq-9ec25.firebaseapp.com",
      databaseURL: "https://sharq-9ec25-default-rtdb.firebaseio.com",
      projectId: "sharq-9ec25",
      storageBucket: "sharq-9ec25.appspot.com",
      messagingSenderId: "613514564466",
      appId: "1:613514564466:web:c76f60d1a5d151689e83eb",
      measurementId: "G-BGWW40HYBJ"
    };


initializeApp(firebaseConfig); // initialize Firebase

const asyncStorage = AsyncStorage;

const FirebasePhoneAuth = () => {
  const [phoneNumber, setPhoneNumber] = useState(""); //  для номера телефона
  const [verificationCode, setVerificationCode] = useState(""); //  для кода подтверждения
  const [confirmationResult, setConfirmationResult] = useState(null); //  для результатов 

  const sendVerificationCode = async () => {
    const auth = getAuth();
    const appVerifier = null; //  reCAPTCHA

    try {
      // Отправка кода подтверждения на указанный номер телефона
      const confirmation = await signInWithPhoneNumber(auth, phoneNumber, appVerifier);
      setConfirmationResult(confirmation); // Сохранение результатов подтверждения для последующего использования
    } catch (error) {
      Alert.alert("Ошибка", "Не удалось отправить код подтверждения");
    }
  };
  // Подтверждение кода подтверждения
  const confirmVerificationCode = async () => {
    try {
      await confirmationResult.confirm(verificationCode);
      Alert.alert("Успех", "Номер телефона успешно подтвержден");

      // Сохранение номера телефона в AsyncStorage
      await asyncStorage.setItem("phoneNumber", phoneNumber);
    } catch (error) {
      Alert.alert("Ошибка", "Не удалось подтвердить номер телефона");
    }
  };

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder="Введите номер телефона"
        onChangeText={(value) => setPhoneNumber(value)}
      />
      <Button onPress={sendVerificationCode} title="Отправить код подтверждения" />

      {confirmationResult && (
        <>
          <TextInput
            style={styles.input}
            placeholder="Введите код подтверждения"
            onChangeText={(value) => setVerificationCode(value)}
          />
          <Button onPress={confirmVerificationCode} title="Подтвердить код подтверждения" />
        </>
      )}
    </View>
  );
};
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
      },
      input: {
        width: "80%",
        height: 40,
        borderWidth: 1,
        marginBottom: 20,
        paddingHorizontal: 10,
      },
    });
export default FirebasePhoneAuth;

2

Answers


  1. When you call getAuth() for an instance of App that hasn’t initialized its Auth object, it will call initializeAuth() for you. In your code, you do this inside sendVerificationCode() which leads to the warning you see.

    To make sure that initializeAuth() is called before you consume it using getAuth() in any of your components, you should place it immediately below the call to initializeApp(). It’s best practice to do this in a common place such as a file called firebase.js or similar:

    // ./services/firebase.js
    import { initializeApp, getApp } from "firebase/app";
    import { initializeAuth, getAuth, getReactNativePersistence } from 'firebase/auth';
    import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';
    
    const firebaseConfig = {
      /* ... */
    };
    
    // initialize Firebase App
    const app = initializeApp(firebaseConfig);
    // initialize Firebase Auth for that app immediately
    initializeAuth(app, {
      persistence: getReactNativePersistence(ReactNativeAsyncStorage)
    });
    
    export { app, auth, getApp, getAuth };
    

    Then in your component, you’d bring it in and use as normal:

    // ./components/someComponent.jsx
    import { getApp, getAuth } from "../services/firebase";
    
    /* component code */
    
    Login or Signup to reply.
  2. I encountered the same problem I just solved it thanks to the previous comment
    Before I created a file at the root of my folder that I named fireConfig.js the file contains the following code

    // Import the functions you need from the SDKs you need
    import { initializeApp, } from "firebase/app";
    import { initializeAuth, getReactNativePersistence  } from "firebase/auth";
    import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';
    // TODO: Add SDKs for Firebase products that you want to use
    // https://firebase.google.com/docs/web/setup#available-libraries
    
    // Your web app's Firebase configuration
    const firebaseConfig = {
      apiKey: 
      authDomain: 
      projectId:
      storageBucket: 
      messagingSenderId: 
      appId: 
    };
    
    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
    
    initializeAuth(app, {
      persistence: getReactNativePersistence(ReactNativeAsyncStorage)
    });
    
    
    export default app;
    

    Then in another file named form.js
    always at the root of my folder create the following code

    import React, { useState, useEffect } from "react";
    import {
      StyleSheet,
      Text,
      View,
      TextInput,
      Button,
    } from "react-native";
    
    import { app } from "./fireConfig"
    import {getAuth, createUserWithEmailAndPassword } from "firebase/auth";
    
    
    
    
    const auth = getAuth(app);
    
    
    const Form = () => {
      const [email, setEmail] = useState("");
      const [password, setPassword] = useState("");
    
      useEffect(() => {
        // Initialiser le formulaire
        setEmail("");
        setPassword("");
      }, []);
    
      const handleLogin =async () => {
            
        await createUserWithEmailAndPassword(auth, email, password)
        .then((userCredential) => {
            // Signed in 
            const user = userCredential.user;
          
            // ...
        })
        .catch((error) => {
            const errorCode = error.code;
            const errorMessage = error.message;
            // ..
        });
    
      };
    
      const handleRegister = () => {
        // Effectuer une requête d'enregistrement
        // ...
      };
    
      return (
        <View style={styles.container}>
          <Text style={styles.title}>Formulaire de connexion</Text>
          <TextInput
            placeholder="E-mail"
            style={styles.input}
            value={email}
            onChangeText={(text) => setEmail(text)}
          />
          <TextInput
            placeholder="Mot de passe"
            style={styles.input}
            value={password}
            onChangeText={(text) => setPassword(text)}
            secureTextEntry={true}
          />
          <Button
            title="Connexion"
            style={styles.button}
            onPress={handleLogin}
          />
          <Button
            title="Enregistrer"
            style={styles.button}
            onPress={handleRegister}
          />
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
      },
      title: {
        fontSize: 24,
        fontWeight: "bold",
      },
      input: {
        width: 200,
        height: 40,
        borderColor: "gray",
        borderWidth: 1,
        borderRadius: 5,
      },
      button: {
        width: 100,
        height: 40,
        backgroundColor: "blue",
        borderRadius: 5,
      },
    });
    
    export default Form;
    
    List item
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search