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

React Native中Firebase Auth结合ReactNativeAsyncStorage持久化失效

解决React Native Firebase Auth持久化用户数据失效问题

你的核心问题是:Firebase Auth初始化后需要从AsyncStorage异步加载用户数据,但现有代码没有监听Auth状态变化,也没有等待加载完成就判断用户状态,导致重启App时初始拿到null,后续数据加载后也无法更新Context,最终错误跳转。

以下是具体修复步骤:

1. 改造SessionProvider,监听Auth状态变化

修改SessionProvider.tsx,用useState维护用户状态,通过onAuthStateChanged监听Firebase Auth的状态变化,确保Context中的用户数据实时同步:

import { useState, useEffect, PropsWithChildren } from 'react';
import { GoogleAuthProvider, signInWithCredential, signOut, onAuthStateChanged, User } from 'firebase/auth';
import { Google } from '@react-native-google-signin/google-signin';
import { auth } from './firebaseConfig';
import { router } from 'expo-router';

export function SessionProvider(props: PropsWithChildren) {
  const [request, response, promptAsync] = Google.useAuthRequest({
    iosClientId: '',
    androidClientId: '',
    webClientId: '',
  });
  // 用state维护用户状态,初始为null
  const [user, setUser] = useState<User | null>(null);
  // 标记Auth是否完成初始化加载
  const [isAuthLoading, setIsAuthLoading] = useState(true);

  // 监听Auth状态变化,组件挂载时启动
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
      setIsAuthLoading(false); // 加载完成,更新状态
    });
    // 组件卸载时取消监听,避免内存泄漏
    return unsubscribe;
  }, []);

  // 处理Google登录响应,等待登录完成再跳转
  useEffect(() => {
    if (response?.type === 'success') {
      const { id_token } = response.params;
      const credential = GoogleAuthProvider.credential(id_token);
      signInWithCredential(auth, credential)
        .then(() => {
          router.navigate('/(tabs)');
        })
        .catch((error) => {
          console.error('登录失败:', error);
        });
    }
  }, [response]);

  return (
    <SessionContext.Provider value={{
      signIn: promptAsync,
      signOut: () => signOut(auth),
      session: user?.uid,
      user,
      // 合并加载状态:Auth加载中 或 Google请求未准备好
      isLoading: isAuthLoading || !request,
    }}>
      {props.children}
    </SessionContext.Provider>
  );
}

2. 修改Index组件,等待Auth加载完成再跳转

原来的Index组件在Auth未加载完成时就判断用户状态,导致错误跳转。现在添加加载状态判断,等待Auth初始化完成后再处理:

import { View, ActivityIndicator } from 'react-native';
import { Redirect } from 'expo-router';
import { useSession } from '../contexts/SessionContext'; // 替换为你的Context路径

const Index = () => {
  const { user, isLoading } = useSession();

  useEffect(() => {
    console.warn(user, 'index');
  }, [user]);

  // Auth加载中时显示加载动画,避免提前判断
  if (isLoading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator size="large" />
      </View>
    );
  }
  
  if (user) {
    return <Redirect href="/(tabs)"/>;
  }
  return <Redirect href="/welcome" />;
};
export default Index;

3. 检查基础配置和依赖

  • 确认已安装@react-native-async-storage/async-storage,Expo项目无需手动链接,原生项目需执行npx pod-install(iOS)或配置AndroidManifest。
  • 核对firebaseConfig.ts中的initializeAuth配置,确保persistence: getReactNativePersistence(ReactNativeAsyncStorage)没有拼写错误。
  • 检查Google登录的Client ID是否正确配置,登录失败会导致用户数据无法持久化。

关键注意事项

  • 不要直接用auth.currentUser作为Context值,它是同步属性,初始为null,Firebase异步加载完成后不会自动触发组件重渲染,必须通过onAuthStateChanged监听更新状态。
  • 登录成功后,等待signInWithCredential的Promise完成再跳转,确保用户数据已写入AsyncStorage。

内容的提问来源于stack exchange,提问作者LoskiPublis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:39:52