Chris Voss
Chris Voss

Reputation: 798

firestore.onSnapshot callback function is blocking render process

I am using Firestore's onSnapshot() method to listen to a collection of ~5,000 documents. In the callback passed to onSnapshot, I am taking the snap and formatting the docs into an array and object.

db.onSnapshot(snap => {
      const list = [];
        const ref = {};
        for (let i = 0, size = snap.size; i < size; i++) {
          const doc = snap.docs[i];
          const id = doc.id;
          const data = doc.data();
          list.push(data);
          ref[id] = { ...data };
        }
    // Save list and ref to redux store.
  }

This process has been working well with smaller collections. However, now with this larger collection, when a user submits a new document to the collection, the "success" prompt that a user sees is blocked by the for loop.

To elaborate: When a user submits a new document, db.add(newDocument) is called. In the .then() we are re-rendering the page to show the user a confirmation message. At the same time though, the snapshot listener has detected a change in the collection and is now looping over all 5,000 documents again. This only takes a second or two but it produces a noticeable "lag" for the user.

How should this process be handled?

Upvotes: 0

Views: 348

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317760

You should probably:

  • Preserve the value of ref for as long as the listener stays attached - don't recreate it each time.
  • Iterate snap.docChanges so you will only have to process those changes that will result in your prior ref contents to change. This will be indicated in the type of the change.

This should drastically reduce the number of objects being created and destroyed every time something changes.

Upvotes: 2

Related Questions