How to listen for a specific Firestore document creation event

1,038 views
Skip to first unread message

Thijs Koerselman

unread,
Nov 13, 2017, 10:41:03 AM11/13/17
to Firebase Google Group
I am implementing a command/response pattern where the user writes to a command collection by calling `add` with a payload under his own userId, and then gets the data from a similar response path.

However the code below doesn't work, because onSnapshot can not listen for a document that hasn't yet been created. This would be easy to solve with an onCreate handler, which does exist for cloud functions. 

This is using [redux-firestore](https://github.com/prescottprue/redux-firestore) and some of my app helper functions, but you'll get the idea. The command and response document structures use { payload, error} similar to [FSA](https://github.com/acdlite/flux-standard-action)

export async function register(fs: any, userId: string) {
 
try {
   
// issue a new command
   
const command = await fs.add(
     
{ collection: `commands/${userId}/register` },
     
{ payload: fs.firestore.FieldValue.serverTimestamp() }
   
);


   
// wait for the response to be written
    fs
.onSnapshot(
     
{ collection: `responses/${userId}/register`, doc: command.id },
     
function onNext(doc) {
         
// an error might have occurred at application level
       
const err = doc.get('error');
       
if (err) {
         
return notify.error({ title: 'Failed to register', message: err.message });
       
}
       
const payload = doc.get('payload');
        notify
.json(payload);
     
},
     
function onError(err) {
        notify
.error(err);
     
}
   
);
 
} catch (err) {
    notify
.error(err);
 
}
}


Why is there no such thing? 

The only scalable solution I can think of is to store the response data as a child in the command document. But I'm wondering if I'm not overlooking some API...

Kato Richardson

unread,
Nov 13, 2017, 4:17:51 PM11/13/17
to Firebase Google Group
Hello Thijs,

It's true that onSnapshot() will return a null value before it's created. But that won't cancel the listener, so I'm not sure what you mean by "because onSnapshot can not listen for a document that hasn't yet been created". You can just use onSnapshot() and check for snapshot.exists == true to capture the initial create event, and then cancel the listener.

This works better than an onCreate() event model as well, as the behavior here becomes pretty non-deterministic when you add in temporary loss of connectivity on mobile devices (i.e. I could miss create events while offline).

☼, Kato

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/18ba9aa3-743b-45aa-b48a-456083f771b4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Kato Richardson | Developer Programs Eng | kato...@google.com | 775-235-8398

Thijs Koerselman

unread,
Nov 28, 2017, 10:19:39 AM11/28/17
to Firebase Google Group
Hi Kato,

I initially missed this reply. That would be perfect. I can't remember exactly why I made the assumption that onSnapshot doesn't work for this, but I guess it was because of the null return value and I didn't investigate further.

Good point about connectivity loss. I was already considering adding timeout/retry mechanism, but that feels clumsy especially given Firebase's offline capabilities.

Thanks for your help! 

Best,
Thijs
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.

To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/18ba9aa3-743b-45aa-b48a-456083f771b4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kato Richardson

unread,
Nov 28, 2017, 11:43:24 AM11/28/17
to Firebase Google Group
Glad it help.s If you have any more questions, let us know! : )

To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.

To post to this group, send email to fireba...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages