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

Firestore获取当前登录用户姓名失败:显示undefined且提示用户未找到

解决Firestore无法获取登录用户name和surname字段的问题

问题根源分析

  1. 控制台输出User not found!,说明Firestore的users集合中不存在与当前登录用户UID匹配的文档,或者文档路径配置错误。
  2. 你直接从Auth返回的currentUser对象中取name和surname,但Auth对象本身只包含邮箱、UID等认证信息,name和surname是存在Firestore文档中的,所以会显示undefined undefined。

分步解决方案

1. 先确认Firestore数据正确性

  • 登录Firebase控制台,进入Firestore数据库,检查users集合下是否有以当前登录用户UID命名的文档
  • 确认该文档内是否包含name和surname字段,字段名要和代码中使用的完全一致(大小写敏感)

2. 分离状态管理

新增一个状态变量存储从Firestore获取的用户资料,避免和Auth用户对象混淆:

const [currentUser, setCurrentUser] = useState(null);
const [userProfile, setUserProfile] = useState(null); // 新增状态

3. 修改getUserDoc函数

获取到Firestore文档数据后,更新userProfile状态:

async function getUserDoc() {
  if (!currentUser) {
    console.error("No current user!");
    return;
  }
  const userRef = doc(db, "users", currentUser.uid);
  const userDoc = await getDoc(userRef);
  if (userDoc.exists()) {
    const userData = userDoc.data();
    console.log("User data:", userData);
    setUserProfile(userData); // 保存Firestore用户数据到状态
  } else {
    console.log("User not found!");
    // 可选:如果文档不存在,可引导用户完善资料
  }
}

4. 修改UI渲染逻辑

从userProfile中获取姓名字段,处理加载状态:

<h3>
  {userProfile ? `${userProfile.name} ${userProfile.surname}` : '加载中...'} <br/>
  <span>{currentUser ? currentUser.email : ''}</span>
</h3>

修改后的完整代码

import React, { useState, useEffect, useRef } from 'react';
import EditIcon from '@mui/icons-material/Edit';
import SettingsIcon from '@mui/icons-material/Settings';
import HelpIcon from '@mui/icons-material/Help';
import LogoutIcon from '@mui/icons-material/Logout';
import '../../styles/familyTree.css';
import profile_pic from '../../pages/familyTree/aaa.jpg';
import { auth, db} from '../../../firebase';
import Authentication from '../../../Authentication';
import { doc, getDoc } from "firebase/firestore";

function FamilyTree() {

  const [currentUser, setCurrentUser] = useState(null);
  const [userProfile, setUserProfile] = useState(null); // 新增用户资料状态
  const [open, setOpen] = useState(false);
  const menu = useRef();

  useEffect(() => {
    const handler = (e) => {
      if (!menu.current.contains(e.target)) {
        setOpen(false);
      }
    };

    document.addEventListener('mousedown', handler);
    return () => {
      document.removeEventListener('mousedown', handler);
    };
  }, []); // 补全依赖数组,避免重复绑定事件

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((user) => {
      setCurrentUser(user);
      if (user) {
        setUserProfile(null); // 用户切换时重置资料
      }
    });
    return () => unsubscribe();
  }, []);

  async function getUserDoc() {
    if (!currentUser) {
      console.error("No current user!");
      return;
    }
    const userRef = doc(db, "users", currentUser.uid);
    const userDoc = await getDoc(userRef);
    if (userDoc.exists()) {
      const userData = userDoc.data();
      console.log("User data:", userData);
      setUserProfile(userData);
    } else {
      console.log("User not found!");
    }
  }
  
  useEffect(() => {
    if (currentUser) {
      getUserDoc();
    }
  }, [currentUser]);
  
  return (
    <div className="menu">
      <div className="menu-wrapper" ref={menu}>
        <div className="menu-main" onClick={() => setOpen(!open)}>
          <img src={profile_pic} alt="profile pic"></img>
        </div>

        <div className={`dropdown ${open ? 'active' : 'inactive'}`}>
          <h3>
            {userProfile ? `${userProfile.name} ${userProfile.surname}` : '加载中...'} <br/>
            <span>{currentUser ? currentUser.email : ''}</span>
          </h3>
          <ul>
            <DropdownItem href="./manageAccount" text="Edit Profile" icon={<EditIcon />} />
            <DropdownItem href="./manageAccount" text="Settings" icon={<SettingsIcon />} />
            <DropdownItem href="./manageAccount" text="Help" icon={<HelpIcon />} />
            <DropdownItem href="/" text="Logout" icon={<LogoutIcon />} onClick={() => {
              auth.signOut();
              console.log(`${currentUser?.email} has been logged out`); // 添加可选链避免报错
            }} />
          </ul>
        </div>
      </div>
    </div>
  );
}

function DropdownItem(props) {
  return (
    <li className="dropdown-items">
      {props.icon}
      <a href={props.href} className="items" onClick={props.onClick}> {props.text}</a>
    </li>
  );
}

export default Authentication(FamilyTree);

额外优化点

  • 第一个useEffect补全了空依赖数组,避免每次渲染都重复绑定/解绑事件
  • 登出时使用可选链currentUser?.email,避免用户未登录时出现报错
  • 用户切换时重置userProfile状态,保证数据一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:02:55