【问题标题】:firestore onsnapshotListner with pagination带分页的firestore onsnapshotListner
【发布时间】:2020-08-23 22:04:09
【问题描述】:

我有一个网络应用程序可以从集合中获取文档的实时更新。但是集合大小太高了。因此,在不应用限制的情况下获取数据是不可能且无效的。所以对查询进行一些限制是非常重要的。现在我将数据作为 50 的一部分。我已经通过了参考 Firestore reactive pagination 。此链接中解释的逻辑运行良好。

但在下面的代码中存在一个混淆,即此处如何计算读取的文档。因为根据代码首先我使用普通的get() 方法获取文档作为 50 个文档的块。之后我将一个侦听器附加到来自get() 方法的响应。所以 Firestore 将添加额外的 50 个读取还是仅 50 个?

这是我所做的代码

var messages = [] 
var listeners = []    // list of listeners
var start = null      // start position of listener
var end = null        // end position of listener

function getMessages(chatId) {

// query reference for the messages we want

let ref = db.collection('chats').doc(chatId)
.collection('messages')

// single query to get startAt snapshot

ref.orderBy('createdAt', 'desc')
.limit(50).get()
.then((snapshots) => {

// save startAt snapshot

start = snapshots.docs[snapshots.docs.length - 1]

// create listener using startAt snapshot (starting boundary)

let listener = ref.orderBy('createdAt')
  .startAt(start)
  .onSnapshot((messages) => {
    // append new messages to message array
    messages.forEach((message) => {
      // filter out any duplicates (from modify/delete events)         
      messages = messages.filter(x => x.id !== message.id)
      messages.push(message.data())
    })
  })

  // add listener to list

  listeners.push(listener)
})
}


 function getMoreMessages(chatId) {

let ref = db.collection('chats').doc(chatId)
.collection('messages')

// single query to get new startAt snapshot

ref.orderBy('createdAt', 'desc')
.startAt(start)
.limit(50).get()
.then((snapshots) => {

 // previous starting boundary becomes new ending boundary

  end = start
  start = snapshots.docs[snapshots.docs.length - 1]

  // create another listener using new boundaries     

  let listener = ref.orderBy('createdAt')
  .startAt(start).endBefore(end)
  .onSnapshot((messages) => {
    messages.forEach((message) => {
      messages = messages.filter(x => x.id !== message.id)
      messages.push(message.data())
    })
  })
  listeners.push(listener)
})
}

// call to detach all listeners
function detachListeners() {
 listeners.forEach(listener => listener())
 }

【问题讨论】:

    标签: typescript google-cloud-firestore


    【解决方案1】:

    这将花费 50 次文档读取:

    ref.orderBy('createdAt', 'desc').limit(50).get()
    

    那么这将再次花费至少相同数量的文档读取:

    ref.orderBy('createdAt').startAt(start).endBefore(end).onSnapshot(...)
    

    或者可能更多,这取决于在侦听器处于活动状态时这些文档的更新频率。

    Firestore 无法在分页的同时进行实时更新。像这样的定制解决方案会很昂贵。

    【讨论】:

    • 感谢您的回复,有没有办法使用 onSnapshotListner 实现分页,firebase 中没有任何关于此的文档
    • 正如我所说:“Firestore 没有提供一种在分页的同时进行实时更新的简便方法”
    猜你喜欢
    • 2018-10-26
    • 2019-08-18
    • 2021-09-27
    • 2019-01-13
    • 2019-05-29
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多