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

如何解决Firebase Auth与Firestore配合时的竞态问题?

问题根源

首次加载/浏览器刷新时,Firebase Auth还没完成初始化,直接读取auth.currentUser会得到undefined,导致后续无法获取用户邮箱并查询Firestore。而代码热重载时,Auth已经初始化完毕,能正常拿到用户数据,这就是出现这种时好时坏情况的根本原因。

解决办法

不要直接读取auth.currentUser,改用Firebase Auth的状态监听机制,等用户登录状态确定后再执行Firestore查询:

修改后的完整代码

import { doc, getDoc, getFirestore } from 'firebase/firestore';
import { auth, onAuthStateChanged } from '../firebase'; // 导入状态监听方法
import { useState, useEffect } from 'react';

const Main = () => {
  const db = getFirestore();
  const [userName, setUserName] = useState("");

  const getUser = async (currentUser) => {
    if (!currentUser) return; // 用户未登录时直接返回,避免无效查询

    const userEmail = currentUser.email;
    const docRef = doc(db, 'useraccounts', userEmail);
    const docSnap = await getDoc(docRef);

    if (docSnap.exists()) {
      setUserName(docSnap.data().first);
    } else {
      console.log("未找到该用户的账户记录");
    }
  };

  useEffect(() => {
    // 监听用户登录状态变化
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        // 用户已登录,执行Firestore查询
        getUser(user);
      } else {
        // 用户未登录,清空用户名状态
        setUserName("");
      }
    });

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

  return (
    <div>
      {userName ? `Welcome, ${userName}` : "加载中..."}
    </div>
  );
};

export default Main;

核心修改说明

  • 新增onAuthStateChanged监听用户登录状态,确保在Auth初始化完成、用户状态就绪后再执行数据查询。
  • 调整getUser函数,接收用户对象作为参数,避免依赖未就绪的auth.currentUser。
  • 添加组件卸载时的监听清理逻辑,防止内存泄漏。
  • 增加加载状态提示,优化用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:10:40