IjzerenHein / firestorter

Use Google Firestore in React with zero effort, using MobX 🤘
http://firestorter.com
MIT License
378 stars 50 forks source link

Silent observer #76

Open RWOverdijk opened 5 years ago

RWOverdijk commented 5 years ago

Hey, it's me again.

I just thought of a cool feature, I think. Silent observers! They don't trigger onSnapshot or anything, they just listen to Collections.

Whenever onSnapshot is triggered for that collection (through the usual processes) a callback is triggered. The silent observer doesn't care if onSnapshot is open, or closed, it only cares about updates.

Use case:

I want to maintain a list of timestamps for chats. When a new message arrives in the Messages collection I know onSnapshot is active otherwise my observer wouldn't have been informed of changes. This also means the chat is active, otherwise onSnapshot wouldn't be open. In that case I want to set the last timestamp to now so I know that any messages before now have been read.

Thoughts?

IjzerenHein commented 5 years ago

Hey. Just read your text for the third time, but I still don't get what you're trying to say :)

Could you maybe provide an example/API or pseudo code that explains the use-case?

RWOverdijk commented 5 years ago

@IjzerenHein I tend to do that, sorry.

Pseudo code:

const someCollection = new Collection('some');

// Called from anywhere. Not necessarily a component. 
someCollection.observe(() => {
  // Stuff changed.
  // The collection was subscribed for updates (onSnapshot())
  //   and something happened.
});

The gist: I will be notified of any and all changes made when there is an active onSnapshot listener. This observer will persist for as long as the Collection instance lives. So when the onSnapshot listener gets disabled (because the view is no longer active) and then enabled again (because the view has been rendered again) my observer will still receive updates.

More information

This is more for context. Feel free to skip, I know it's rather lengthy.

The way I'm doing it now is creating my own firestore collection and setting the ref of the collection. I control the onSnapshot myself which I'd rather not be doing.

All of this is related to my other issue where I want to stop listening when the uid gets set to null. My plan is to maintain an MST store that contains a map of chats in the format:

interface Chat { id: string, lastRead: number; }

Whenever the onSnapshot() callback gets called, I will walk through the snapshot adding a new Chat to my store for each chat id that isn't part of my Map yet. Likewise I will remove all Chats that aren't in the snapshot.

By doing this I can safely update the lastRead timestamp of a chat whenever the chat is active, and persist it to firebase only when the app gets killed (or periodically, of course). I'll have less writes (considering it's for group chats of up to 50 users) and a lower bill 😄

RWOverdijk commented 5 years ago

@IjzerenHein Another project, another example.

I have to preload images when they get updated in a dashboard. So, while I do want to use collections to display data, I also want to have access to updated records so I can preload the urls they contain.

IjzerenHein commented 5 years ago

@RWOverdijk Hi Roberto. Sorry, I've been too busy with other things, I'll try to get back to with a week or two. Cheers

RWOverdijk commented 5 years ago

I'm not trying to rush you. No hurry :) I know what it's like. Besides, I have a workaround, even if it's a bit lengthy.