React v18+Firebase v9 如何向已有用户文档新增anime子集合
问题根因
你的代码存在3个核心逻辑错误,导致Auth认证用户和Firestore用户数据无法匹配:
- 创建用户文档时使用
addDoc自动生成随机文档ID,没有和Auth生成的用户唯一标识绑定,完全无法通过用户身份定位到对应Firestore文档 - 混淆了Firebase Auth的返回结构:
createUserWithEmailAndPassword返回的是用户凭证对象,实际用户身份数据在凭证的user字段下,且Auth用户不存在id属性,唯一终身不变的标识是uid字段 - 错误读取返回值属性:
addDoc返回的是文档引用对象,本身不存储你写入的email字段,之前写的setEmail(newUser.email)实际拿到的是undefined
修正方案
核心原则:直接使用Auth返回的用户uid作为Firestore中Users集合的文档ID,不需要额外用邮箱做匹配,这是Auth和Firestore数据关联的标准实践,不会出现匹配错位问题。
1. 修正注册逻辑
替换原有注册代码,不要用addDoc生成随机用户文档ID:
const register = async () => { try { // 创建Auth认证账号,拿到用户凭证 const userCredential = await createUserWithEmailAndPassword(auth, registerEmail, registerPassword) // 提取真实认证用户对象 const authUser = userCredential.user // 用Auth用户的uid作为Users集合下的文档ID,写入用户基础数据 await setDoc(doc(db, "Users", authUser.uid), { email: registerEmail, createTime: new Date() }); // 邮箱直接用注册时输入的值即可,不需要从文档返回值取 setEmail(registerEmail) navigate("/home"); } catch(error) { console.log(error.message); } }
2. 修正子集合写入逻辑
写入anime子集合时,直接取当前登录用户的uid拼接路径即可,不需要额外查询用户文档:
const createAnime = async () => { // 获取当前已登录的用户,未登录时直接拦截 const currentUser = auth.currentUser if (!currentUser) { console.log("用户未登录,无法创建内容") return } // 路径直接对应当前用户uid下的anime子集合 const addAnime = await addDoc(collection(db,"Users", currentUser.uid, "anime"),{ title, genre, numb, comment, rating, aid }) }
注意:不要用邮箱作为用户关联依据,用户后续可以在Auth中修改绑定邮箱,会导致关联失效。
uid是Auth侧为每个用户生成的终身不变的唯一标识,所有和用户绑定的私有数据(个人信息、收藏、操作记录)都应该挂在对应uid的文档路径下。
内容的提问来源于stack exchange,提问作者Deividas
相关产品推荐
相关产品推荐

