React中Firestore安全添加条目:规则与认证问题排查
问题解决步骤
1. 修复代码里的基础错误与异步逻辑
先纠正几个明显的代码问题:
- 邮箱字符串多了个逗号:
'email@email.com,'改成'email@email.com' - React状态更新错误:
setUserID = userCredential.user.uid;应该是函数调用setUserID(userCredential.user.uid); - 异步逻辑顺序错误:登录是异步操作,直接在后面写集合引用和写入操作时,
userID还未被赋值,且await必须放在async函数内。
修正后的完整逻辑示例(可放在提交按钮点击事件或useEffect中):
const handleSaveAnswers = async () => { const auth = getAuth(); try { // 完成登录 const userCredential = await signInWithEmailAndPassword(auth, 'email@email.com', 'thisisthepassword'); setAuthTrue(1); const userId = userCredential.user.uid; // 根据需求选择对应的数据结构写入 // 情况1:每个用户仅存一份答案,用文档存储(文档ID为用户UID) const userAnswerDoc = doc(db, "answers", userId); await setDoc(userAnswerDoc, { q1: '1', q2: '2', q3: '3' }); // 情况2:每个用户需存储多份答案,用嵌套集合 // const userAnswersCollection = collection(db, "answers", userId, "user_answers"); // await addDoc(userAnswersCollection, { // q1: '1', // q2: '2', // q3: '3' // }); } catch (error) { setAuthTrue(0); console.error('操作失败:', error); } };
2. 解决集合引用段数错误
你遇到的Invalid collection reference错误,核心原因是:Firestore中集合引用的路径段数必须是奇数(比如answers是1段,answers/{userId}/user_answers是3段),而answers/userIdhere是2段,属于文档引用,不能用collection()创建。
根据需求调整数据结构:
- 单份答案:用
doc(db, "answers", userId)创建文档引用,搭配setDoc写入。 - 多份答案:创建嵌套集合
answers/{userId}/user_answers,用collection()创建集合引用,搭配addDoc写入新答案。
3. 调整Firestore安全规则
当前规则匹配的是根目录下的{userId}集合,和你的answers集合不匹配,需要调整为仅允许认证用户读写自己的答案数据:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 对应情况1:answers集合下的文档ID等于用户UID match /answers/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } // 对应情况2:嵌套集合的规则 // match /answers/{userId}/user_answers/{answerDoc} { // allow read, write: if request.auth != null && request.auth.uid == userId; // } } }
内容的提问来源于stack exchange,提问作者green_arrow
相关产品推荐
相关产品推荐

