Firebase addDoc()返回成功却未添加文档,如何验证写入有效性?
解决Firestore addDoc写入不存在集合仍返回成功的问题
首先明确核心原因:Firestore的设计逻辑是自动创建不存在的集合,所以你把集合名改成"NoSuchCollection"后,addDoc并没有失败,而是帮你新建了这个集合并写入了文档,这就是控制台返回成功的原因。
下面是几种更优的验证/拦截方法:
1. 用Firestore安全规则限制合法集合
这是最推荐的方案,既能保证数据安全,又能自动拦截非法集合的写入请求。通过安全规则只允许写入你指定的集合(比如"emails"),当尝试写入不存在的集合时,请求会被拒绝,addDoc会抛出权限错误,直接进入catch块。
示例安全规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 仅允许写入"emails"集合,可根据需求添加权限验证(如用户登录状态) match /emails/{document} { allow write: if true; } // 默认拒绝其他所有集合的写入操作 match /{document=**} { allow write: if false; } } }
2. 前端提前校验集合名称
在发起addDoc请求前,先检查目标集合名是否在你预设的合法列表中,非法集合直接拦截,不用发起请求。
示例代码:
// 预设合法集合列表 const VALID_COLLECTIONS = ["emails"]; const addEmail = async (data: { email: string; }) => { console.log("Sending data to firebase"); // 校验集合名是否合法 const targetCollection = "emails"; // 若集合名是动态传入,替换为对应变量 if (!VALID_COLLECTIONS.includes(targetCollection)) { console.error("Invalid collection name: ", targetCollection); return; } try { const result = await addDoc(collection(db, targetCollection), {email: data!.email}); console.log("Document written with ID: ", result.id); } catch (e) { console.error("Error adding document: ", e); } }
3. 写入后验证文档存在性(备选方案)
如果必须验证文档是否真的写入,可以用getDoc查询addDoc返回的DocumentReference,因为这个ref指向的就是刚尝试写入的文档,若查询结果存在则说明写入成功。不过这种方法会多一次网络请求,效率不如前两种。
示例代码:
const addEmail = async (data: { email: string; }) => { console.log("Sending data to firebase"); try { const docRef = await addDoc(emailsCollectionRef, {email: data!.email}); const docSnap = await getDoc(docRef); if (docSnap.exists()) { console.log("Document successfully saved: ", docSnap.data()); } else { console.error("Failed to save document"); } } catch (e) { console.error("Error adding document: ", e); } }
内容的提问来源于stack exchange,提问作者Nox
相关产品推荐
相关产品推荐

