似乎有一种更干净,更优化的方法来查询Firestore集合,在每个文档上调用doc.data()
,然后返回数组作为结果。将文档推送到结果数组感觉偶然的顺序。
此代码有很多步骤:
result
变量doc.data()
result
数组result
数组 function getStories() {
var result = [];
db.collection('stories').get().then(querySnapshot => {
querySnapshot.forEach(doc => result.push(doc.data()));
})
return result;
}
代码工作正常,但似乎我们可以用更少的步骤以更简洁的方式编写此代码。
答案 0 :(得分:0)
首先,定义一个map
函数以用于Firebase(命名为mapSnapshot
,因为它专门用于Firebase):
const mapSnapshot = f => snapshot => {
const r = [];
snapshot.forEach(x => { r.push(f(x)); });
return r;
}
然后,您可以只使用Promise
和mapSnapshot
:
function getStories() {
return db.collection('stories').
get().
then(mapSnapshot(doc => doc.data()));
}
用法示例:
getStories().then(docs => ... do whatever with docs ...)
说实话,如果将其用作一次性解决方案,它并不是更少的代码。但这很整洁,它允许创建可重用的抽象。因此,例如,您可以使用mapSnapshot
创建一个snapshotToArray
函数,该函数可以在需要将DataSnapshot从firebase转换为普通Array
时重用:
const snapshotToArray = mapSnapshot(x => x);
请注意:此完全不依赖于任何集合名称。您可以将其与 any 集合中的 any DataSnapshot一起使用,以将其转换为Array
!
这还不是全部。您可以轻松地从DataSnapshot的内容到包含其中内容的常规Array
中创建函数:
const readDocsData = mapSnapshot(x => x.data());
同样,这看起来没什么大不了–除非您意识到,还可以创建一个fromFirebase
函数,该函数可以查询各种数据集:
const fromFirebase = (name, transform = x => x) => {
return db.collection(name).get().then(transform);
}
然后您可以像这样使用它:
fromFirebase('stories', readDocsData).then(docs => {
// do what you want to do with docs
});
这样,作为程序员,您立即注意到最终结果的步骤就更少了。但是它产生了(尽管是可重用的)几个中间步骤,每个中间步骤都隐藏了一点抽象。
答案 1 :(得分:0)
您共享的代码实际上不起作用,如George所评论。由于Firestore异步加载数据,因此您总是在加载数据之前返回数组。因此您的数组将为空。
在代码中:
function getStories() {
var result = [];
db.collection('stories').get().then(querySnapshot => {
querySnapshot.forEach(doc => result.push(doc.data()));
})
return result;
}
var result = getStories();
console.log(result.length);
将会记录:
0
要解决此问题,您想返回一个承诺,该承诺将在数据加载后解决。遵循以下原则:
function getStories() {
var result = [];
return db.collection('stories').get().then(querySnapshot => {
querySnapshot.forEach(doc => result.push(doc.data()));
return result;
})
}
因此,这基本上增加了两个return语句,使您的result
冒起泡沫,然后作为getStories
的承诺返回。要调用此功能,您需要执行以下操作:
getStories().then(result => {
console.log(result.length);
})
然后将记录正确数量的结果。