Transaction callbacks in Firebase may fire multiple times. To understand why that is, let's see how this operation may be executed.
Let's start with this logic: if the current value is null, you want it to become "byebye".
settingsRef.transaction(function(current) {
if (!current) {
return "byebye";
}
return current;
}, function(error, committed, snapshot) {
}, true);
The Firebase client doesn't yet know the value of your settings
node, so it invokes your transaction with an assumption: that the current value is null
. It then sends the combination of the value if gave to you and the value you returned to the Firebase server.
The Firebase server compares the current value in the database ("hello"
) against the value it provided to you and decides they don't match ("hello" <> null
). So it sends the current value ("hello"
) back to the client.
The Firebase client invokes your callback again. This time it passes in the value it heard from the server ("hello"
):
settingsRef.transaction(function(current) {
if (!current) {
return "byebye";
}
return current + "!";
}, function(error, committed, snapshot) {
}, true);
So now your function returns "hello!"
. Firebase again sends the value it gave you and the value you returned to the server: "hello"
and "hello!"
. The server does the same comparison as before and if the value in the database is still "hello"
it sets the new value you specified "hello!"
.
This is called a compare-and-set operation and explains why your callback may be called multiple times.