React Redux Firestore无法向不存在的集合添加文档问题排查
问题核心
你遇到的情况是:向Firestore未存在的集合写入文档时,代码进入成功分支并返回DocumentReference,但即时检查文档不存在,控制台也看不到新集合/文档;刷新页面后操作恢复正常。
原因分析
异步代码混用导致变量异常
你同时使用了await和.then(),这种写法会导致drinks变量无法正确获取DocumentReference:await等待的是add()返回的Promise,但.then()未返回result,最终drinks实际是undefined。后续用drinks.path访问属性存在潜在错误,即使能打印路径,也可能导致后续验证逻辑出错。本地缓存与云端同步的时序差
Firebase SDK默认启用本地缓存,写入操作会先成功写入本地缓存(触发.then()回调),但同步到云端需要短暂时间。此时用默认的get()方法(优先读取本地缓存),或云端还未完成同步,就会出现“文档不存在”的误判;刷新页面后,SDK重新从云端拉取数据,就能看到正确的文档。控制台显示延迟
Firestore控制台不会实时刷新数据,且空集合不会显示,只有当集合存在至少一个文档时才会出现。即使云端写入成功,控制台可能需要几秒后刷新才能看到新内容。
解决步骤
1. 修正异步代码写法
统一用await或.then()链式调用,避免混用,确保变量正确获取DocumentReference:
// 推荐await写法 const firestore = useFirestore(); const data = { date: Date.now(), state: HISTORY_ITEM_NOT_PAID, drinks: addedDrinks }; try { const drinksRef = await firestore.add(`users/${auth.uid}/drinks`, data); console.log("Success", drinksRef); // 直接用获取到的DocumentReference验证,无需通过path字符串 const docSnapshot = await drinksRef.get(); if (docSnapshot.exists) { console.log(`${drinksRef.path} exists`); } else { console.log(`${drinksRef.path} does not exists`); } } catch (error) { console.log("Error", error); }
2. 强制从云端读取验证
如果需要即时验证云端写入结果,读取时指定源为server,跳过本地缓存:
// 强制从云端拉取数据,避免缓存干扰 const docSnapshot = await drinksRef.get({ source: 'server' });
3. 检查安全规则
确保Firestore安全规则允许当前用户写入users/{uid}/drinks集合:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{uid}/drinks/{doc} { allow write: if request.auth.uid == uid; } } }
若规则拒绝写入,SDK会先在本地缓存标记成功,但云端会拒绝,刷新后文档就会消失,这也是常见的“假成功”原因。
4. 控制台刷新验证
写入操作完成后,等待3-5秒再手动刷新Firestore控制台,即可看到新创建的集合和文档。
内容的提问来源于stack exchange,提问作者Karl Wolf

