Firestore报错‘User document does not exist’:Linktree类项目数据显示异常
排查Firestore用户文档读取失败(显示undefined+“文档不存在”报错)
问题背景
开发类Linktree项目,使用Firebase认证+Firestore数据库:
- 认证功能正常,用户数据已存入
users集合 - 进入用户控制面板后,数据区域显示
undefined,同时弹出“User document does not exist”报错 - 已尝试修改Firestore规则(甚至开放全读写权限)、硬编码真实用户UID,问题仍未解决
相关代码
用户控制面板核心逻辑
import { db, auth } from "@/lib/firebaseConfig"; import { getDoc, doc } from "firebase/firestore"; import { signOut, onAuthStateChanged } from "firebase/auth"; import { useEffect, useState } from "react"; import { useRouter } from "next/router"; export default function Dashboard() { const [userData, setUserData] = useState(null); const router = useRouter(); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, async (user) => { if (user) { console.log("User authenticated:", user.uid); try { const userDocRef = doc(db, "users", user.uid); const userDoc = await getDoc(userDocRef); if (userDoc.exists()) { console.log("User document found:", userDoc.data()); setUserData(userDoc.data()); } else { console.log("User document does not exist."); alert("User document does not exist."); } } catch (error) { console.error("Error fetching user data:", error); alert( `Error fetching user data: ${error instanceof Error ? error.message : String(error)}` ); } } else { console.log("No user is authenticated. Redirecting to login."); router.push("/"); } }); return () => unsubscribe(); }, [router]); return ( <div> {/* 渲染userData的区域 */} {userData ? <div>{userData.email}</div> : <div>Loading...</div>} </div> ); }
Firebase配置文件(firebaseConfig.ts)
import { initializeApp } from "firebase/app"; import { getAuth } from "firebase/auth"; import { getFirestore } from "firebase/firestore"; const firebaseConfig = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, }; const app = initializeApp(firebaseConfig); const db = getFirestore(app); const auth = getAuth(app); export { db, auth };
Firestore规则(最新版本)
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if true; } } }
排查与解决方案
1. 核对Auth UID与Firestore文档ID的一致性
- 打开浏览器控制台,查看打印的
User authenticated:后的UID,与Firestore控制台中users集合的文档ID逐字符对比- 注意:Firebase Auth的UID由小写字母、数字、连字符组成,确保创建用户文档时没有使用错误的ID(比如用邮箱、自定义ID代替UID)
- 如果ID不匹配,修改用户注册逻辑,确保用Auth返回的
user.uid作为Firestore文档ID:// 注册示例代码 import { setDoc, doc } from "firebase/firestore"; import { createUserWithEmailAndPassword } from "firebase/auth"; const handleRegister = async (email: string, password: string) => { try { const userCredential = await createUserWithEmailAndPassword(auth, email, password); const user = userCredential.user; // 用user.uid作为文档ID写入用户数据 await setDoc(doc(db, "users", user.uid), { email: user.email, createdAt: new Date() }); } catch (error) { console.error("Registration failed:", error); } };
2. 验证Firebase配置与规则生效
- 确认
firebaseConfig.ts中的projectId与Firebase控制台的项目ID完全一致 - 检查环境变量是否正确加载:Next.js中
NEXT_PUBLIC_前缀的变量会暴露给客户端,开发环境需重启服务器生效,生产环境需重新构建 - 确认Firestore规则已发布:修改规则后需在Firebase控制台点击发布按钮,确保新规则生效
3. 修复组件渲染逻辑(避免undefined显示)
- 添加加载状态,防止在
userData未加载完成时渲染:const [loading, setLoading] = useState(true); // 在useEffect的try/catch块末尾添加: setLoading(false); // 渲染时处理: return ( <div> {loading ? ( <div>加载中...</div> ) : userData ? ( <div>用户邮箱:{userData.email}</div> ) : ( <div>未找到用户数据</div> )} </div> );
4. 检查Firebase SDK版本兼容性
- 确保
package.json中firebase相关依赖的版本一致,避免版本不匹配导致的API调用异常:"dependencies": { "firebase": "^10.12.0", // 其他依赖 }
5. 直接测试硬编码读取(排除Auth逻辑干扰)
- 暂时替换代码中的
user.uid为Firestore中存在的文档ID,测试是否能读取数据:const userDocRef = doc(db, "users", "已知存在的文档ID");- 如果能读取,说明Auth返回的UID与文档ID不匹配;如果仍不能读取,检查Firebase配置或网络连接
内容的提问来源于stack exchange,提问作者Grenish Rai
相关产品推荐
相关产品推荐

