React Native中Firestore任务去重时documentSnapshot.exists为undefined
问题根源
你打印documentSnapshot.exists得到undefined的核心原因是对象类型混淆:
你通过.where()条件查询调用.get()拿到的返回值,不是单文档快照DocumentSnapshot,而是查询结果快照QuerySnapshot。你在.then()回调里将参数命名为documentSnapshot,进一步强化了单文档快照的认知偏差,但实际该参数传入的是整组查询结果。这类QuerySnapshot对象本身不存在exists属性,因此读取值为undefined。
两类快照对象的核心差异:
- 直接通过固定文档路径获取单个文档(如
.collection('A').doc('文档ID').get())返回DocumentSnapshot,这类对象才具备.exists布尔属性,用来判断对应路径的文档是否存在 - 带条件查询的
.get()返回QuerySnapshot,它没有exists属性,判断是否有匹配文档的内置属性为:empty:布尔值,值为true时代表没有任何匹配查询条件的文档size:数值,代表匹配到的文档总数量
代码修正方案
调整判断逻辑,直接通过QuerySnapshot的内置属性判断任务是否重复,同时优化async/await与Promise链式调用混用的冗余写法,修正后的实现:
addTask = async (task) => { const useruid = firebase.auth().currentUser.uid; console.log("task : " + task); try { const querySnapshot = await firebase.firestore() .collection("Tasks") .where('task', '==', task) .get(); console.log('匹配到的重复任务数:', querySnapshot.size); // 存在匹配结果则提示重复,终止流程 if (!querySnapshot.empty) { console.log('This task already exists!'); return; } // 无重复结果则执行任务添加 await firebase.firestore().collection('Tasks').add({ userProducer: useruid, task: task }) console.log('Task added!'); } catch (error) { console.log("error = " + error) } }
注意事项
- 原代码中
.then()后单独包裹代码块的大括号属于冗余语法,可移除避免阅读歧义 - 因为重复判断依赖
task字段的相等匹配查询,需在Firestore控制台为task字段配置单字段索引,否则查询会触发索引缺失的报错 - 统一使用
async/await编写异步逻辑,可避免多层.then()嵌套造成的逻辑混乱
内容的提问来源于stack exchange,提问作者user123456
相关产品推荐
相关产品推荐

