DEV Community

Cover image for Firebase Firestore Initial Payload with onSnapshot
Si Le
Si Le

Posted on • Originally published at Medium on

Firebase Firestore Initial Payload with onSnapshot

Firebase Firestore Initial Payload with onSnapshot

Image from https://firebase.google.com/images/social.png

NOTE : This approach only works for web because Firestore doesn’t offer caching for web. On iOS and Android, you must take another approach to handle initial payload and subsequent updates due to caching. The first response from a subscription on iOS or Android will come from cache. Second response is new updates from Firestore and subsequent responses are updates/create/destroy only.

I’ve been using Firebase for a while now. One of the problems I’ve had with Firebase is this weird behaviour when you want to subscribe to a query, it returns the whole result on the first call and returns new/updated documents afterward.

Let’s say I want to ignore the initial load and only listen to new changes. That’s just purely subscription. How do you know which one is the first call?

Firebase doesn’t provide any ways to check whether the result set is the first one. I’ve tried stackoverflow to see if anybody encountered the same problem. This thread is promising:

Stackoverflow Thread https://stackoverflow.com/questions/49798693/differentate-between-first-time-querysnapshot-and-change-listener-in-firestore

Looks like the first query snapshot only contains added event. Sure, but what if you want to listen to new document events too? Do you have to handle the first added event the same as subsequent added events?

In my case, I want to ignore the first payload altogether and only listen to new updates. A new update can be an added event other other events. Therefore, checking whether it’s an added event for first payload doesn’t work.

What if I can count the number of invocation of the callback function and ignore the first invocation all together? Here’s a generic function wrapper that count the number of times the wrapped function is called.

createFnCounter() takes 2 arguments, first is the function being wrapped, and second is the number of invocation needed before the wrapped function is called. Therefore, createFnCounter(foo, 1) will only call foo on the second call. I’m pretty sure some names in this function can be more explicit but you get the idea (in case you want to discuss, I’m down for it).

How do you use this function? I have a collection named activities that contains all the activities happened to my chat channels collection. When a user sent a message to another user, there’s a new activity created/modified to notify the chat client, it’s saying, “Hey, there’s a new activity on this channel, do your thing”. The client received the event, and does its things. When the client initialize, I subscribe to activities collection as follow.

Let’s incorporate createFnCounter to only receive updates and ignore initial payload.

Too verbose, I know, but 6 months from now when I look back at this code, I’ll know what happened.

What if I want to get that initial payload too but do something different with it? Well, here we go

There you go, now you have a way to distinguish between initial load and subsequent updates when subscribing to documents on Firestore. Have other methods? Let me know!

Thanks for reading! ≈

Top comments (0)