我是否正确地通过巨大的Firebase系列进行分页?

时间:2017-08-07 16:40:21

标签: node.js firebase firebase-realtime-database promise

我正试图找到一种方法来迭代Firebase数据库中大量数据的所有对象。

我的最佳尝试如下,但我发现它很奇怪有几个原因:

  1. startAt()值始终具有包容性。因此,在获取100个元素之后,我不得不使用我最后一次获取的键作为startAt的参数,这导致最后一个项被再次提取
  2. DataSnapshot' forEach方法不允许使用索引计数进行回调,因为您认为它基于JS的标准,所以我必须创建手动索引 - 不确定它是否适用于所有情况,因为我不确定forEach是否完全同步工作
  3. 这是我的代码,假设我的集合位于users

    const mapAllTripsPaginated = function (database, childSnapshotCallback, start = '', limit = 100, totalNb = 0) {
      return database.ref('/users').orderByKey().startAt(start).limitToFirst(limit).once('value').then((snapshot) => {
        let childrenPromises = []
        let lastChildKey = null
        let idx = 0
        snapshot.forEach((childSnapshot) => {
          lastChildKey = childSnapshot.key
          if (start !== '' && idx === 0) {
            // console.log(`Skipping ${childSnapshot.key} as 1st element of page`)
          } else {
            childrenPromises.push(childSnapshotCallback(childSnapshot))
          }
          idx = idx + 1
        })
        return Promise.all(childrenPromises)
        .then((result) => {
          let newTotal = totalNb + result.length
          if (snapshot.numChildren() === limit) {
            console.log(`Paginating from ${lastChildKey}`)
            return mapAllTripsPaginated(database, childSnapshotCallback, start = lastChildKey, limit = limit, totalNb = newTotal)
          } else {
            // Done paginating
            return newTotal
          }
        })
      })
    }
    

    关于如何使这种方法更优雅的任何想法?

1 个答案:

答案 0 :(得分:1)

  1. Firebase查询包括其开始和结束条件。您确实必须对客户端上的重叠项进行重复数据删除。

  2. Firebase的Snapshot.forEach()是同步操作。

  3. 我通常根据已经拥有该项目的密钥进行重复数据删除。这也将消除对idx计数器的需求。

    snapshot.forEach((childSnapshot) => {
      if (lastChildKey !== childSnapshot.key) {
        childrenPromises.push(childSnapshotCallback(childSnapshot))
      }
      lastChildKey = childSnapshot.key
    })