如何在 React Native/ 上保留 Firebase 用户身份验证

Seb*_*ina 7 firebase reactjs react-native firebase-authentication expo

我已经尝试让它发挥作用有一段时间了。我使用 Expo 构建了我的应用程序,其中很大一部分是允许用户离线时使用该应用程序。这应该工作的方式是每当我打开应用程序时,我就会被带到屏幕上Login。从这里,一个useEffect钩子将确定用户是否登录,如果登录,它将重定向到该Home页面。这在用户在线时有效,但由于某种原因,每当我构建应用程序并在 iPhone 上关闭它(完全关闭它),然后在打开飞行模式并断开 Wi-Fi 的情况下重新打开时,我都会卡在屏幕Login上我无法做任何事情,因为我没有任何联系。


这是我的firebase.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// import { getAuth, initializeAuth } from "firebase/auth";
import {
  getReactNativePersistence,
  initializeAuth,
} from "firebase/auth/react-native";
import { getFirestore, enableIndexedDbPersistence } from "firebase/firestore";

import AsyncStorage from "@react-native-async-storage/async-storage";

const firebaseConfig = {...};

// Initialize Firebase

const app = initializeApp(firebaseConfig);

export const db = getFirestore(app);

export const auth = initializeAuth(app, {
  persistence: getReactNativePersistence(AsyncStorage),
});
Run Code Online (Sandbox Code Playgroud)

这是我的useEffect屏幕上的Login

 useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      console.log("USER: " + user + " " + user?.email);
      if (user) {
        navigation.replace("Home");
      }
    });
  }, []);
Run Code Online (Sandbox Code Playgroud)

小智 14

在下面链接的帮助下,我在回复我自己为此提出的 gitHub 问题时解决了这个问题:

https://github.com/firebase/firebase-js-sdk/issues/7152

https://github.com/firebase/firebase-js-sdk/issues/7164

解决此问题的步骤是:

版本

"世博会": "~48.0.6",

“反应”:“18.2.0”,

npm i firebase ("firebase": "^9.19.0")

npm 我 @react-native-async-storage/async-storage ("@react-native-async-storage/async-storage": "1.17.11")

npm 我 @react-native-firebase/auth ("@react-native-firebase/auth": "^17.4.0")

创建 firebaseConfig.js 文件

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

export const firebaseApp = initializeApp({
  // enter your firebase project details
  apiKey: "..........",
  authDomain: "..........",
  projectId: "..........",
  storageBucket: "..........",
  messagingSenderId: "..........",
  appId: "..........",
  measurementId: ".........."
});

export const auth = initializeAuth(firebaseApp, {
  persistence: getReactNativePersistence(AsyncStorage),
});
Run Code Online (Sandbox Code Playgroud)

创建App.js

import {StyleSheet} from 'react-native';
import AppMain from './AppMain';

const App = () => {
  return (
    <AppMain />
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff'
  }
});

export default App;
Run Code Online (Sandbox Code Playgroud)

创建AppMain.js

import { useEffect, useState } from 'react';
import { StyleSheet, Text, View, Button, Dimensions, TextInput, ActivityIndicator, Pressable } from 'react-native';
import { auth } from './firebaseConfig';

import { signInWithEmailAndPassword, onAuthStateChanged, signOut } from "firebase/auth";

const { width, height } = Dimensions.get('window');
console.log(width, height);

export default function App() {
  const [user, setUser] = useState(null);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      console.log("USER IS STILL LOGGED IN: " , user);
      if (user) {
        setUser(user);
      }
    });
  }, [user]);


  const handleLogin = () => {
    signInWithEmailAndPassword(auth, email, password)
      .then((userCredential) => {
        console.log('User logged in successfully:',  userCredential);
        setUser(userCredential);
      })
      .catch((error) => {
        console.log('Error', error);
      });
  };

  const handleLogout = () => {
    signOut(auth)
      .then(() => {
        console.log('User logged out successfully:');
        setUser(null);
      })
      .catch((error) => {
        console.log('Error', error);
      });
  };

  if (!user) {
    return (
      <View style={[styles.container]}>
        <TextInput
        placeholder="Email"
        value={email}
        onChangeText={(text) => setEmail(text)}
        />
        <TextInput
        placeholder="Password"
        secureTextEntry={true}
        value={password}
        onChangeText={(text) => setPassword(text)}
        />
        <Button title="Login" onPress={handleLogin} />
        <Text style={styles.text} type='black' >{'\nYou Are Logged Out.'}</Text>
      </View>
    );
  };

  if (user) {
    return (
      <View style={styles.container}>
        <Text style={[styles.text,{fontWeight: 'bold'}]}>{"USER STILL LOGGED IN: \n\n"}</Text>
        <Text style={styles.text}>{'email: ' + user?.email}</Text>
        <Text style={styles.text}>{'uid: ' + user?.uid}</Text>
        <Text style={styles.text}>{"\nAccess Token:\n\n" + user?.accessToken}</Text>
        <Button title="Logout" onPress={handleLogout} />
      </View>
    );
  };
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    width: width,
    height: height,
    backgroundColor: '#fff',
    justifyContent: 'center',
    alignItems:'center'
  },
  text: {
    color:'#000',
    textAlign: 'center',
    paddingHorizontal:20
  }
});
Run Code Online (Sandbox Code Playgroud)

以下步骤应让用户在刷新应用程序后保持登录状态。它还处理登录和注销功能。这个问题困扰了我一段时间:)。