React使用Firebase9.8写入Firestore报文档引用错误如何解决
问题现象
React.js项目中使用9.8版本Firebase写入数据时,触发如下报错:
Uncaught (in promise) FirebaseError: Invalid document reference. Document references must have an even number of segments,but Users has 1.
触发报错的原有业务代码:
const onSubmitHandler = async (event) => { console.log(event); console.log("saving data to database request is Trigered...") // Hear we push the data in firestore databae await setDoc(doc(db, "Users",), { name:collectionOfStates},{merge: true} ).then(() => console.log("Data Save in firebase")).catch((error) => { console.log(error); }) }
报错根因
Firestore的路径规则是集合、文档交替层级嵌套:
- 奇数段路径指向集合(比如
Users是1段,属于集合引用) - 偶数段路径指向具体文档(比如
Users/xxx_userid是2段,属于文档引用)setDoc是写入具体文档的方法,仅支持接收文档引用作为参数,原有代码存在四个核心问题:
- 构建文档引用时
doc(db, "Users",)只传了1个路径段,指向Users集合本身,且参数末尾多余的逗号导致文档ID参数缺失,不符合文档引用的段数要求 setDoc参数传参错位,{merge: true}是setDoc的第三个配置参数,原有代码把它放到了写入数据对象的同级括号外,参数顺序错误- 同时混用
async/await和.then/.catch属于冗余写法,容易引发逻辑混乱 - 表单提交事件未阻止默认行为,容易触发页面跳转打断异步写入流程
修复方案
根据业务场景二选一即可:
场景1:指定固定文档ID写入(比如用用户UID作为文档ID,适合用户信息类数据)
补全文档路径的ID参数,修正参数顺序,统一用async/await的try/catch捕获错误:
const onSubmitHandler = async (event) => { event.preventDefault(); // 阻止表单默认提交跳转 console.log(event); console.log("saving data to database request is Trigered...") try { // 路径补全具体文档ID,替换为你业务里的唯一标识即可,比如登录用户的auth.uid await setDoc( doc(db, "Users", "替换为你的目标文档ID"), { name: collectionOfStates }, // 写入的数据对象 { merge: true } // merge配置为setDoc的第三个参数,不要放错位 ) console.log("Data Save in firebase") } catch (error) { console.log(error); } }
场景2:自动生成随机文档ID写入(适合评论、动态这类不需要固定ID的数据)
不需要手动指定文档ID时,直接用addDoc方法传入集合引用即可,Firestore会自动生成全局唯一的文档ID:
// 注意先引入addDoc、collection方法 import { addDoc, collection } from "firebase/firestore"; const onSubmitHandler = async (event) => { event.preventDefault(); console.log(event); console.log("saving data to database request is Trigered...") try { await addDoc( collection(db, "Users"), // 直接传入集合引用 { name: collectionOfStates } // 写入的数据对象 ) console.log("Data Save in firebase") } catch (error) { console.log(error); } }
后续排查校验规则
- 调用
doc()构建文档引用时,始终校验路径段数为偶数:集合/文档/子集合/子文档的交替规则下,每多一层文档就多2段路径 setDoc、updateDoc、deleteDoc这类文档操作方法,禁止传入奇数段的集合引用- 写路径参数时不要在末尾加多余的逗号,避免漏传后续参数
- 表单提交场景必须加
event.preventDefault(),避免默认跳转打断异步请求
内容的提问来源于stack exchange,提问作者Platinum Jubille Collection
相关产品推荐
相关产品推荐

