I have web app to get realtime updates of documents from a collection. But the collection size is too high. So getting data without applying limit not possible and not effective. So it is very important to implement some limit on query. Right now i am taking the data as a chunk of 50. I have gone trough the reference Firestore reactive pagination . The logic explained in this link working in good manner.
But there is a confusion in below code that how the document read will be calculated here. Because according to the code first i am getting documents using normal get()
method as a chunk of 50 documents.After that i am attaching a listener to the response from the get()
method.So will Firestore add extra 50 reads or just 50?
Here is the code what i have done
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())
}