1

I want to load my data into chunks of 10 in react. I am listening for document addition using onSnapshot() firestore method. I want to paginate data and at the same time allow the recent addition to come to the top. How to apply this in the code below -

db.collection('palettes').orderBy("createdAt").onSnapshot(snapshot => { 
    snapshot.docChanges().forEach(change => {

          if (change.type === "added") {
               setPalette( prevPalette => ([
                   { id: change.doc.id, ...change.doc.data() },
                     ...prevPalette
                    ]))
                    setIsLoading(false)
                }
            })
     })
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Stack
  • 429
  • 1
  • 4
  • 12

1 Answers1

3

I think you should save state of last document for pagination and realtime updates

Example


const getPalettes = (pageSize, lastDocument) => new Promise((resolve, reject) => {
  let query = db.collection('palettes')
    .orderBy("createdAt")

  if(lastDocument) {
    query = query.startAt(lastDocument)
  }

  query = query.limit(pageSize);

  return query.onSnapshot(query => {
    const docs = query.docs.map(pr => ({pr.id, ...pr.data()}))
    resolve(docs);
  });
})

let unsubscribe = getPalettes(10).then(newPalettes => {
  setPalette(palettes => [...palettes, newPalettes]);
  lastPalette = newPalettes[newPalettes.length -1];
  setLastPalette(lastPalette);
  unsubscribe();
})

unsubscribe = getPalettes(10, lastPalette).then(newPalettes => {
  setPalette(palettes => [...palettes, newPalettes]);
  lastPalette = newPalettes[newPalettes.length -1];
  setLastPalette(lastPalette);
  unsubscribe();
})


const listenForLatestPalettes = (lastDocument, callback) => {
  return db.collection('palettes')
    .orderBy("createdAt")
    .startAt(lastDocument)
    .onSnapshot(callback);
}

const callback = snapshot => {
  for(let change of snapshot.docChanges()) {
    if (change.type === "added") {
      setPalette(palettes => {
        const palette = { id: change.doc.id, ...change.doc.data() };
        return [...palettes.filter(pal => pal.id !== id], palette];
      })
    }
  }
}

unsubscribe = listenForLatestPalettes(lastDocument, callback);
Józef Podlecki
  • 10,453
  • 5
  • 24
  • 50