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

Firebase Firestore 已认证用户无法读取数据问题求助

Firebase Firestore数据读取时auth.currentUser为null的解决方案

你的问题核心在于Firebase Auth的初始化是异步过程,组件中fetchData的执行时机早于Auth完成用户状态恢复的时机,所以auth.currentUser还没赋值就被调用了,日志顺序也印证了这一点——数据请求的日志先于Auth状态就绪的日志输出。

方案1:通过onAuthStateChanged监听用户状态触发数据请求

不要直接在组件挂载时调用fetchData,而是通过Auth的状态监听回调,确保用户状态就绪后再执行数据读取:

修改src/app/home/page.jsx代码:

import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import { auth, firestore } from '../../../../firebase';
import { collection, getDocs } from 'firebase/firestore';
import Swal from 'sweetalert2';
import createNewProject from '../../api/makeNewProject'

const Page = () => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // 监听用户状态变化
    const unsubscribe = auth.onAuthStateChanged((currentUser) => {
      if (currentUser) {
        setUser(currentUser);
        // 用户状态就绪后调用数据获取
        fetchData(currentUser);
      } else {
        setUser(null);
        console.log("用户未登录");
      }
    });

    // 组件卸载时取消监听,避免内存泄漏
    return () => unsubscribe();
  }, []);

  const fetchData = async (currentUser) => {
    console.log("current user:", currentUser);
    const dataRef = collection(firestore, 'data');
    console.log("data ref", dataRef);
    
    // 执行实际的数据读取操作
    try {
      const querySnapshot = await getDocs(dataRef);
      const dataList = querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
      console.log("获取到的数据:", dataList);
    } catch (error) {
      console.error("读取数据失败:", error);
      Swal.fire('错误', '数据读取失败', 'error');
    }
  };

  return (
    <div>
      {user ? <p>当前登录用户: {user.email}</p> : <p>请先登录</p>}
      {/* 其他组件内容 */}
    </div>
  );
};

export default Page;

方案2:优化Firebase初始化代码(可选)

可以将onAuthStateChanged放在setPersistence的then回调中,确保持久化配置完成后再监听状态,逻辑更严谨:

修改firebase.js代码:

const app = initializeApp(firebaseConfig);
const firestore = getFirestore(app);
const auth = getAuth(app);

// 先配置持久化,再监听用户状态
setPersistence(auth, browserLocalPersistence)
  .then(() => {
    console.log("User Persistence is Local");
    onAuthStateChanged(auth, (user) => {
      if (user) {
        console.log("User is signed in:", user);
      } else {
        console.log("User is signed out");
      }
    });
  })
  .catch((error) => {
    console.error('Error setting persistence:', error);
  });

export { auth, firestore };

关键注意点

  • 禁止直接依赖auth.currentUser获取初始状态:页面刷新后,Firebase需要从本地存储恢复用户会话,这个过程是异步的,初始时auth.currentUser必然为null。
  • 必须通过onAuthStateChanged监听状态:这是Firebase官方推荐的方式,能覆盖登录、登出、会话恢复等所有用户状态变化场景。
  • 你的Firestore规则配置是正确的,只要在用户状态就绪后发起请求,就能通过权限验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:32:28