Firebase 查询集合和合并子集合数据

Posted

技术标签:

【中文标题】Firebase 查询集合和合并子集合数据【英文标题】:Firebase Query Collection And Merge Subcollection Data 【发布时间】:2019-03-27 10:16:42 【问题描述】:

我正在尝试找出一种方法来获取文档集合及其子集合数据。

例如,我的树是……

-locations
 -locationId
   -historic
     -april
       -airTemp: 12.4
       -displayOrder: 4
     -august
       -airTemp: 14.5
       -displayOrder: 9
     -december
       -airTemp: 13.5
       -displayOrder: 12
     etc..

...其中locationId 是一个文档,historic 是其中包含每月文档的子集合。

我知道如何获取***集合项并将其存储到数组中,但我也想将它们的子集合数据(即 jan、feb 等)添加到每个文档中。

  var locations = []

  let ref = db.collection('locations')
  db.collection('locations').get()
  .then(snapshot => 
      snapshot.forEach(doc => 
          let location = doc.data()
          location.id = doc.id
          location.name = doc.name

          // get the historic subcollection data here

      )
  )

如何从每个对象中获取组合数据(集合和子集合),然后将其推送到数组中?

赏金结构错误 每个月都应该是它自己的对象

【问题讨论】:

“我也想将他们的子集合数据(即 1 月、2 月)添加到每个文档中”是什么意思。您的意思是在数据库中还是在读取数据库时在您的前端? @RenaudTarnec 在前端读取数据库 【参考方案1】:

移动/网络客户端库无法在一个查询中获取 Firestore 文档的数据及其子集合文档的数据。

甚至无法获取文档的子集合列表(使用移动/网络客户端库),请参阅https://firebase.google.com/docs/firestore/query-data/get-data#list_subcollections_of_a_document

所以您需要知道子集合的名称才能查询它们,这就是您的情况(name = 'historic')。

您可以执行以下操作。首先,您获取所有父文档,同时使用Promise.all() 并行查询所有“历史”子集合。

    var db = firebase.firestore();

    var promises = []
    db.collection('locations').get()
        .then(snapshot => 
            snapshot.forEach(doc => 
                let location = doc.data()
                location.id = doc.id
                location.name = doc.data().name
                console.log(location);
                promises.push(doc.ref.collection('historic').get());
            )
            return Promise.all(promises);
        )
        .then(results => 
            results.forEach(querySnapshot => 
                querySnapshot.forEach(function (doc) 
                    console.log(doc.id, " => ", doc.data());
                );
            );
        );

注意results 数组的顺序与promises 数组的顺序完全相同。

还要注意,要获取文档项的值(例如 name),您需要使用 doc.data().name 而不是 doc.name

【讨论】:

感谢您的澄清。所以我可以看到这个日志仍然是单独的位置和结果。您如何将每个位置与后续子集合放入 1 个对象中? 你必须结合查询的结果,知道结果和promise数组的顺序是一样的。 不太确定该怎么做 - 这是我在尝试解决这个问题时遇到的主要问题。 使用第一个.then(snapshot => ),您将遍历主文档。您可以在那里填充这些文档数据的数组。然后在results.forEach(querySnapshot => ) 中,您将遍历子集合。如果您知道每个父文档的子集合的数量,这很容易(例如,假设您为每个文档 -jan 和 feb- 设置了 2 个集合,您知道结果数组的前两个元素对应于第一个主文档,依此类推。 如果每个父文档的子集合数量不同,您可以(在父文档中)存储(在父文档中)专用字段中的集合数量,并在循环 `results 数组成员时使用此值识别每个历史文档的父文档。希望这会有所帮助。【参考方案2】:

首先创建一个空数组,例如resultsArray = []。使用简单或复合查询来获取您想要阅读的文档。然后遍历 resultDocuments 创建一个 resultObject 记录您想要的任何属性。在该迭代中,.push(resultObject) 到结果数组。

【讨论】:

以上是关于Firebase 查询集合和合并子集合数据的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Web Firebase - 通过子集合字段获取集合

新的 Firebase Firestore DocumentDb 如何为大型子集合建模

如何将子集合添加到 Firebase Cloud Firestore 中的文档

如何在 Firebase + Firestore + Flutter 中使用 StreamBuilder 将所有子集合数据获取到 Widget

并查集

在地图上显示 firebase 子集合的引脚 - Flutter