查询集合并将数据作为列表返回的更简洁的方法?

时间:2019-01-24 12:34:12

标签: javascript arrays google-cloud-firestore

似乎有一种更干净,更优化的方法来查询Firestore集合,在每个文档上调用doc.data(),然后返回数组作为结果。将文档推送到结果数组感觉偶然的顺序。

此代码有很多步骤:

  1. 创建了一个新的result变量
  2. 进行查询以检索“故事”集合
  3. 对于每个文档,我们称为doc.data()
  4. 我们将每个文档推送到result数组
  5. 返回result数组
  function getStories() {
    var result = [];
    db.collection('stories').get().then(querySnapshot => {
        querySnapshot.forEach(doc => result.push(doc.data()));
    })
    return result;
  }

代码工作正常,但似乎我们可以用更少的步骤以更简洁的方式编写此代码。

2 个答案:

答案 0 :(得分:0)

首先,定义一个map函数以用于Firebase(命名为mapSnapshot,因为它专门用于Firebase):

const mapSnapshot = f => snapshot => {
  const r = [];
  snapshot.forEach(x => { r.push(f(x)); });
  return r;
}

然后,您可以只使用PromisemapSnapshot

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);
})

然后将记录正确数量的结果。

相关问题