Expo React Native中Firebase v10.1.0用户登录持久化问题
React Native Expo + Firebase v10.1.0 登录状态持久化问题解决
我用React Native Expo开发应用,使用Firebase v10.1.0版本,当前遇到的问题:用户登录后杀死应用进程,登录状态丢失,必须重新输入账号密码。已将auth.onAuthStateChanged放置在AuthContext中,相关代码如下:
启动首页(已登录跳转逻辑)代码
const { user, loading } = useContext( AuthContext ); // 用户已登录则跳转到HomeScreen useEffect( () => { Alert.alert( user?.email ); if ( user ) { navigation.navigate( 'Home' ); } }, [ loading, user ] );
authContext.js代码
import { createContext, useState, useEffect } from "react"; import { Alert } from "react-native"; import { auth, db } from "../config/firebase"; export const AuthContext = createContext( { user: null, setUser: () => { }, admin: false, } ); export const AuthProvider = ( { children } ) => { const [ user, setUser ] = useState( null ); const [ loading, setLoading ] = useState( true ); useEffect( () => { const unsubscribe = auth.onAuthStateChanged( async ( user ) => { if ( user ) { // 使用auth.currentUser获取用户最新认证信息 setUser( auth.currentUser ); setLoading( false ); } else { setUser( null ); setLoading( false ); } } ); // 清理:组件卸载时取消监听 return () => unsubscribe(); }, [] ); return ( <AuthContext.Provider value={ { user, loading } }> { children } </AuthContext.Provider> ); };
用户登录代码
auth.signInWithEmailAndPassword( email, password ) .then( async userCredential => { navigation.reset( { index: 0, routes: [ { name: "Home" } ], } ); } )
firebase.js代码
import firebase from 'firebase/compat/app'; import 'firebase/compat/auth'; import 'firebase/compat/firestore'; import 'firebase/compat/storage'; const firebaseConfig = { apiKey: "xxx", authDomain: "xxx", databaseURL: "xxx", projectId: "xxx", storageBucket: "xxx", messagingSenderId: "xxx", appId: "xxx" }; let fireApp; if ( !firebase.apps.length ) { fireApp = firebase.initializeApp( firebaseConfig ); } else { fireApp = firebase.app(); } const auth = firebase.auth(); const db = fireApp.firestore(); const storage = firebase.storage(); export { auth, db, storage };
尝试解决时遇到的错误
我尝试添加auth.setPersistence( firebase.auth.Auth.Persistence.LOCAL )解决持久化问题,登录时出现如下错误:
LOG error [TypeError: Cannot read property 'setItem' of undefined]
问题原因及解决方法
1. 修正持久化API调用方式
compat模式下的持久化枚举路径错误,应该用firebase.auth.Persistence.LOCAL而非firebase.auth.Auth.Persistence.LOCAL,修改登录代码:
// 在登录前设置持久化 await auth.setPersistence(firebase.auth.Persistence.LOCAL); auth.signInWithEmailAndPassword(email, password) .then(async userCredential => { navigation.reset({ index: 0, routes: [{ name: "Home" }], }); }) .catch(error => { console.error('登录错误:', error); });
2. 优化AuthContext的状态更新逻辑
onAuthStateChanged回调直接使用参数user即可,无需调用auth.currentUser,避免状态更新延迟:
useEffect(() => { const unsubscribe = auth.onAuthStateChanged((user) => { setUser(user); // 直接使用回调返回的user对象 setLoading(false); }); return () => unsubscribe(); }, []);
3. 配置Expo适配的持久化存储
Expo中Firebase Auth的本地持久化依赖AsyncStorage,先安装依赖:
npx expo install @react-native-async-storage/async-storage
然后修改firebase.js,让Firebase使用AsyncStorage作为持久化存储(推荐切换到模块化API):
import { initializeApp } from 'firebase/app'; import { initializeAuth, getReactNativePersistence } from 'firebase/auth/react-native'; import { getFirestore } from 'firebase/firestore'; import { getStorage } from 'firebase/storage'; import AsyncStorage from '@react-native-async-storage/async-storage'; const firebaseConfig = { // 你的配置信息 }; const app = initializeApp(firebaseConfig); // 初始化Auth并指定持久化存储 const auth = initializeAuth(app, { persistence: getReactNativePersistence(AsyncStorage) }); const db = getFirestore(app); const storage = getStorage(app); export { auth, db, storage };
这种方式下,本地持久化会自动生效,无需手动调用setPersistence。
内容的提问来源于stack exchange,提问作者Kal-1
相关产品推荐
相关产品推荐

