Reputation: 474
Firebase atomic increment can be used in update or set. But they don't return the updated value on completion. So, I have to use once('value') immediately after update or set:
var submitref = firebase.database().ref('/sequence/mykey')
return submitref.set(firebase.database.ServerValue.increment(1)).then(_=>{
return submitref.once('value').then(snap=>snap.val());
});
Lets assume 2 threads are executing this code concurrently. submitref.set() will work fine, because of atomic increment. But if they complete submitref.set() at the same time and execute submitref.once('value') at the same time, both threads will receive same incremented value by +2.
Is this a possibility or am I not understanding it correctly?
Upvotes: 0
Views: 273
Reputation: 598718
The increment
operation executes atomically on the server. There is no guarantee in their operation that all clients (or even any client) will see all intermediate states.
Your use-case to keep a sequential, monotonically incremental counter is better suited to a transaction since with a transaction the client controls the new value based on the current value.
Upvotes: 1
Reputation: 317362
JavaScript is a single-threaded language. Every bit of code executes in some order relative to any other bit of code. There is no threading contention except through any native libraries, which is not the case here. Also, Realtime Database pipelines all of its operations over a single connection in the order they were received, so there is a consistent order to its operations as well.
All that said, I imagine you could get into a situation where the two calls to set()
happen before the two calls to once()
, which means they would both show the twice-incremented value.
In this case, you might be better off overall using a listener with on()
in order to simply know the most recent value at any time, and act on it whenever it's seen to change, regardless of what happens after establishing it.
Upvotes: 1