Hi Olivier,
Having a node server listening for changes is a quite common way to extend Firebase functionality.
The only concern I'd have with your approach is that you might miss intermediate values if the node server is down.
- Node script starts listening
- A user changes the value to 1
- Node script receives event and sends email 1
- A user changes the value to 2
- Node script receives event and sends email 2
- Node script dies
- A user changes the value to 3
- A user changes the value to 4
- A user changes the value to 5
- Node script is started again and starts listening
- Node script receives event and sends email 5
In the above scenario, emails 3 and 4 will never be sent. The reason for this is that Firebase will not synchronize the intermediate value changes when the node server reconnects in step 10. Firebase synchronizes state ("the value is 5"), it does not synchronize state changes ("a user changed the value from 4 to 5").
If handling all state changes is required for your use-case, it is better to model the state changes in your database. A simple example of this is when you're trying to keep a counter between multiple clients (always a tricky situation in a distributed system like Firebase). The common method is to store a count in Firebase and then have each client update that value.
/count: 1
ref.child('count').transaction(function(count) {
return (count || 0) + 1;
});
If multiple clients run this code, they're all updating the same location. Not only does that lead to contention, it also leads to the scenario we had before where listeners may not see every update.
The alternative is to not store the count, but the "increments" themselves as a separate action. In that case, the clients would push increments onto a queue:
/increments
ref.child('increments').push(1);
With this model you guarantee that each increment becomes a separate record in the database, so every listener is guaranteed to see each increment. As a nice bonus, this approach also removes the lock contention.
This last approach is used extensively in Firebase's internal processes. We often use
firebase-queue to implement the server-side processes.