Firebase Admin为何仅forEach可遍历Firestore查询结果?
Firestore QuerySnapshot无法用普通for/for-of循环遍历的原因及解决办法
问题原因
Firestore查询返回的response是QuerySnapshot对象,不是普通数组:
- 它没有实现数组的索引访问器,所以用
response[i]直接取值会得到undefined,调用el.data()自然报错,普通for循环也就失效。 - 早期版本的Firebase Admin SDK里,QuerySnapshot没实现ES6迭代器接口,导致
for-of循环无法直接遍历;即便新版本支持,部分环境可能仍需手动转换。 - 而
forEach是QuerySnapshot自身提供的遍历方法,专门适配内部的文档快照结构,所以能正常运行。
解决办法(支持await)
forEach不支持异步回调的等待逻辑,要在循环里用await,可以先把QuerySnapshot转成数组再遍历:
方法1:用QuerySnapshot的docs属性
docs属性直接返回包含所有DocumentSnapshot的数组,直接基于它遍历即可:
// for-of循环(支持await) for (const el of response.docs) { // 这里可以正常使用await执行异步操作 await processOrder(el.data()); console.log(el.data()); } // 普通for循环 for(let i = 0; i < response.docs.length; i += 1) { const el = response.docs[i]; await processOrder(el.data()); console.log(el.data()); }
方法2:展开运算符转数组
用ES6展开运算符把QuerySnapshot转换成普通数组:
const orderDocs = [...response]; for (const el of orderDocs) { await processOrder(el.data()); console.log(el.data()); }
补充说明
- QuerySnapshot的
size属性和docs.length数值完全一致,都是返回的文档总数。 - 转成数组后,
for-of或普通for循环会等待每个循环内的await完成,再进入下一次循环,异步逻辑就能正常执行。
内容的提问来源于stack exchange,提问作者Omar Dulaimi
相关产品推荐
相关产品推荐

