You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:55:53