使用 AsyncStorage 初始化 React Native 的 Firebase Auth 时出现问题

MLS*_*ALA 4 javascript reactjs react-native firebase-authentication

我在通过 Firebase 实施 SMS 身份验证时遇到问题。我一直在尝试研究文档并使用Google寻找解决方案,但到目前为止没有成功。我有一个简单的页面,其中有一个输入字段和一个“发送”按钮。我正在使用 Expo 开发 Android 应用程序。

\n

但是,当尝试为 React Native 初始化 Firebase Auth 时,Expo 给出以下错误:

\n

警告 [2023-09-05T05:59:10.503Z] @firebase/auth: Auth (10.3.1):\n您正在为 React Native 初始化 Firebase Auth,但不提供 AsyncStorage。身份验证状态将默认为内存持久性,并且不会在会话之间保留。为了保持身份验证状态,请安装包“@react-native-async-storage/async-storage”并将其提供给initializeAuth:

\n
import { initializeAuth, getReactNativePersistence } from 'firebase/auth';\nimport ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';\nconst auth = initializeAuth(app, {\n  persistence: getReactNativePersistence(ReactNativeAsyncStorage)\n});\n
Run Code Online (Sandbox Code Playgroud)\n

您能解释一下我该如何解决这个问题吗?我已经安装了包“@react-native-async-storage/async-storage”,但我不明白如何正确使用它来初始化 Firebase Auth。

\n
  import React, { useState } from "react";\n    import { Alert, Button, StyleSheet, TextInput, View } from "react-native";\n    import { initializeApp } from "firebase/app";\n    import { getAuth, signInWithPhoneNumber } from "firebase/auth";\n    import AsyncStorage from "@react-native-async-storage/async-storage";\n    import { initializeAuth, getReactNativePersistence } from 'firebase/auth';\n    import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';\n\n    const firebaseConfig = {\n      apiKey: "AIzaSyD5Qg_t9KR4TmLr2p14E2aODO9UV5RehUE",\n      authDomain: "sharq-9ec25.firebaseapp.com",\n      databaseURL: "https://sharq-9ec25-default-rtdb.firebaseio.com",\n      projectId: "sharq-9ec25",\n      storageBucket: "sharq-9ec25.appspot.com",\n      messagingSenderId: "613514564466",\n      appId: "1:613514564466:web:c76f60d1a5d151689e83eb",\n      measurementId: "G-BGWW40HYBJ"\n    };\n\n\ninitializeApp(firebaseConfig); // initialize Firebase\n\nconst asyncStorage = AsyncStorage;\n\nconst FirebasePhoneAuth = () => {\n  const [phoneNumber, setPhoneNumber] = useState(""); //  \xd0\xb4\xd0\xbb\xd1\x8f \xd0\xbd\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80\xd0\xb0 \xd1\x82\xd0\xb5\xd0\xbb\xd0\xb5\xd1\x84\xd0\xbe\xd0\xbd\xd0\xb0\n  const [verificationCode, setVerificationCode] = useState(""); //  \xd0\xb4\xd0\xbb\xd1\x8f \xd0\xba\xd0\xbe\xd0\xb4\xd0\xb0 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f\n  const [confirmationResult, setConfirmationResult] = useState(null); //  \xd0\xb4\xd0\xbb\xd1\x8f \xd1\x80\xd0\xb5\xd0\xb7\xd1\x83\xd0\xbb\xd1\x8c\xd1\x82\xd0\xb0\xd1\x82\xd0\xbe\xd0\xb2 \n\n  const sendVerificationCode = async () => {\n    const auth = getAuth();\n    const appVerifier = null; //  reCAPTCHA\n\n    try {\n      // \xd0\x9e\xd1\x82\xd0\xbf\xd1\x80\xd0\xb0\xd0\xb2\xd0\xba\xd0\xb0 \xd0\xba\xd0\xbe\xd0\xb4\xd0\xb0 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f \xd0\xbd\xd0\xb0 \xd1\x83\xd0\xba\xd0\xb0\xd0\xb7\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8b\xd0\xb9 \xd0\xbd\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80 \xd1\x82\xd0\xb5\xd0\xbb\xd0\xb5\xd1\x84\xd0\xbe\xd0\xbd\xd0\xb0\n      const confirmation = await signInWithPhoneNumber(auth, phoneNumber, appVerifier);\n      setConfirmationResult(confirmation); // \xd0\xa1\xd0\xbe\xd1\x85\xd1\x80\xd0\xb0\xd0\xbd\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 \xd1\x80\xd0\xb5\xd0\xb7\xd1\x83\xd0\xbb\xd1\x8c\xd1\x82\xd0\xb0\xd1\x82\xd0\xbe\xd0\xb2 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f \xd0\xb4\xd0\xbb\xd1\x8f \xd0\xbf\xd0\xbe\xd1\x81\xd0\xbb\xd0\xb5\xd0\xb4\xd1\x83\xd1\x8e\xd1\x89\xd0\xb5\xd0\xb3\xd0\xbe \xd0\xb8\xd1\x81\xd0\xbf\xd0\xbe\xd0\xbb\xd1\x8c\xd0\xb7\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f\n    } catch (error) {\n      Alert.alert("\xd0\x9e\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0", "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbe\xd1\x82\xd0\xbf\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb8\xd1\x82\xd1\x8c \xd0\xba\xd0\xbe\xd0\xb4 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f");\n    }\n  };\n  // \xd0\x9f\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 \xd0\xba\xd0\xbe\xd0\xb4\xd0\xb0 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f\n  const confirmVerificationCode = async () => {\n    try {\n      await confirmationResult.confirm(verificationCode);\n      Alert.alert("\xd0\xa3\xd1\x81\xd0\xbf\xd0\xb5\xd1\x85", "\xd0\x9d\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80 \xd1\x82\xd0\xb5\xd0\xbb\xd0\xb5\xd1\x84\xd0\xbe\xd0\xbd\xd0\xb0 \xd1\x83\xd1\x81\xd0\xbf\xd0\xb5\xd1\x88\xd0\xbd\xd0\xbe \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd");\n\n      // \xd0\xa1\xd0\xbe\xd1\x85\xd1\x80\xd0\xb0\xd0\xbd\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 \xd0\xbd\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80\xd0\xb0 \xd1\x82\xd0\xb5\xd0\xbb\xd0\xb5\xd1\x84\xd0\xbe\xd0\xbd\xd0\xb0 \xd0\xb2 AsyncStorage\n      await asyncStorage.setItem("phoneNumber", phoneNumber);\n    } catch (error) {\n      Alert.alert("\xd0\x9e\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0", "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb4\xd0\xb8\xd1\x82\xd1\x8c \xd0\xbd\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80 \xd1\x82\xd0\xb5\xd0\xbb\xd0\xb5\xd1\x84\xd0\xbe\xd0\xbd\xd0\xb0");\n    }\n  };\n\n  return (\n    <View style={styles.container}>\n      <TextInput\n        style={styles.input}\n        placeholder="\xd0\x92\xd0\xb2\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb5 \xd0\xbd\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80 \xd1\x82\xd0\xb5\xd0\xbb\xd0\xb5\xd1\x84\xd0\xbe\xd0\xbd\xd0\xb0"\n        onChangeText={(value) => setPhoneNumber(value)}\n      />\n      <Button onPress={sendVerificationCode} title="\xd0\x9e\xd1\x82\xd0\xbf\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb8\xd1\x82\xd1\x8c \xd0\xba\xd0\xbe\xd0\xb4 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f" />\n\n      {confirmationResult && (\n        <>\n          <TextInput\n            style={styles.input}\n            placeholder="\xd0\x92\xd0\xb2\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb5 \xd0\xba\xd0\xbe\xd0\xb4 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f"\n            onChangeText={(value) => setVerificationCode(value)}\n          />\n          <Button onPress={confirmVerificationCode} title="\xd0\x9f\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb4\xd0\xb8\xd1\x82\xd1\x8c \xd0\xba\xd0\xbe\xd0\xb4 \xd0\xbf\xd0\xbe\xd0\xb4\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8f" />\n        </>\n      )}\n    </View>\n  );\n};\n    const styles = StyleSheet.create({\n      container: {\n        flex: 1,\n        justifyContent: "center",\n        alignItems: "center",\n      },\n      input: {\n        width: "80%",\n        height: 40,\n        borderWidth: 1,\n        marginBottom: 20,\n        paddingHorizontal: 10,\n      },\n    });\nexport default FirebasePhoneAuth;\n
Run Code Online (Sandbox Code Playgroud)\n

sam*_*man 13

当您调用尚未初始化其对象getAuth()的实例时,它会为您调用. 在您的代码中,您在内部执行此操作,这会导致您看到警告。AppAuthinitializeAuth()sendVerificationCode()

为了确保在任何组件中initializeAuth()使用它之前调用它,您应该将其放置在对 的调用的正下方。最佳实践是在一个常见的地方执行此操作,例如名为或类似的文件:getAuth()initializeApp()firebase.js

// ./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
const auth = initializeAuth(app, {
  persistence: getReactNativePersistence(ReactNativeAsyncStorage)
});

export { app, auth, getApp, getAuth };
Run Code Online (Sandbox Code Playgroud)

然后在您的组件中,您可以将其引入并正常使用:

// ./components/someComponent.jsx
import { getApp, getAuth } from "../services/firebase";

/* component code */
Run Code Online (Sandbox Code Playgroud)