When the off()
function is called, it will halt the Firebase client from triggering child_added
events for any new incoming data. However, it does not prevent the client from firing child_added
events for existing data that has already been received.
This can lead to some interesting outcomes. For instance, consider the following code snippet:
var ref = new Firebase('https://stackoverflow.firebaseio.com/31069762');
ref.remove();
for (var n = 0; n < 1024; ++n) {
ref.push(n)
}
ref.on('child_added', function(snapshot) {
console.log(snapshot.val());
if (snapshot.val() > 10) {
console.log('off') // Printed multiple times.
ref.off();
}
});
The output of this would be like:
1
2
.
.
.
11
"off"
12
"off"
.
.
.
1024
"off"
Initially, the data for your reference is downloaded as one complete set when you register the listener. Subsequently, all child_added
events are triggered.
Now, let's alter the sequence of the code:
var ref = new Firebase('https://stackoverflow.firebaseio.com/31069762');
ref.remove();
ref.on('child_added', function(snapshot) {
console.log(snapshot.val());
if (snapshot.val() > 10) {
console.log('off') // Printed multiple times.
ref.off();
}
});
for (var n = 0; n < 1024; ++n) {
ref.push(n)
}
In this scenario, we first initiate the listener and then begin pushing values. The resulting output would be:
1
2
.
.
.
11
"off"
By changing the order in this way, the process halts immediately. Since we begin listening for child_added
before any data is present, the initial payload remains empty and each child is subsequently received as a separate update.
Please note that these dynamics rely on the internal mechanisms of the Firebase client, and I have not delved into how it specifically operates in practice. Hence, my concept of the "one initial packet" may differ from reality.
If your goal is to cease processing data after reaching a certain point (e.g., 10
), there are two possible approaches:
Employing a local flag to indicate the completion of processing, as you currently do
Utilizing a Query
to restrict the amount of data fetched by Firebase, rather than filtering on the client side:
ref.orderByValue().endAt(10).on('child_added'...
It is worth noting that the functionality of orderByValue
was introduced in version 2.2.7 of the Firebase JavaScript SDK. It took me some time to discern why it couldn't be utilized in the JSBin environment. :-/