多个Firestore查询,单个承诺/回调

时间:2017-11-29 12:27:06

标签: firebase google-cloud-firestore

我了解Firestore不支持查询的逻辑OR。 我的想法是创建多个查询并在客户端合并结果。 我正在开发一个新闻应用程序,我正在尝试获取包含用户兴趣标签的所有文章(例如技术,音乐等) 普通用户有20个标签,因此我将提出20个不同的请求。

当所有结果到达时,是否有人有链接多个请求并返回唯一承诺的经验。

我正在使用js sdk

我的数据结构:

文章(收藏)

-article (document)
--id: 10
--time: 1502144665
--title: "test title"
--text: "test text"
--tags(obj) 
---technology: 1502144665,
---politics: 1502144665,
---sports: 1502144665

所以我需要创建多个数据库请求,如下所示。

user.tags = ["technology","politics","sports","architecture","business"];

for (var i = 0; i < user.tags.length; i++) {
  db.collection('articles').where(user.tags[i], '>', 0).orderBy(user.tags[i]))
    .get()
    .then(() => {
        // ... push to article array
  });)
}

我试图弄清楚如何在每个请求完成时创建一个promise / callback。

2 个答案:

答案 0 :(得分:5)

您可以在数组中保存每个数据库访问Promise,然后使用Promise.all()获取在每个数据库访问完成时解析的Promise。 (此代码未经过测试,可能包含一些语法错误,但它证明了这一想法。)

user.tags = ["technology","politics","sports","architecture","business"];

var dbPromises = [];
for (var i = 0; i < user.tags.length; i++) {
  dbPromises.push(
      db.collection('articles')
        .where(user.tags[i], '>', 0)
        .orderBy(user.tags[i])
        .get()
  );
}

Promise.all(dbPromises)
    .then(() => {
        // ... push to article array
};

答案 1 :(得分:4)

这是一个ES6友好版本,它使用一些功能范例来降低复杂性

let articles = db.collection('articles')

user.tags = [
  'technology',
  'politics',
  'sports',
  'architecture',
  'business'
]

// map each tag to a firestore query
let queries = users.tags.map(tag => {
  return articles.where(tag, '>', 0).orderBy(tag).get()
})



/*
  Use Promise.all to aggregate the results
  and wait for all of them to complete
 */

Promise.all(queries).then((querySnapshots) => {

  /*
    querySnapshots is an Array[QuerySnapshot]
    reduce all our querySnapshots to only their DocumentReferences
   */

  return querySnapshots.map(qs => qs.docs)
                       .reduce((acc, docs) => [...acc, ...docs])

}).then((matchingArticleRefs) => {

  /*
    matchingArticleRefs is now an Array[DocumentReferences] from firestore
    if no documents matched the queries above it will be an empty array
   */

})