javascript - Firebase Web SDK - Transaction causing on('child_added', func.. to be called -


see jsbin.com/ceyiqi/edit?html,console,output verifiable example.

i have reference listening database point

jobs/<key>/list

where <key> teams unique number

under entry point list of jobs

i have listener on point with

this.jobsref.orderbychild('archived')                     .equalto(false)                     .on('child_added', function(data) { 

i have method following transaction:

ref.transaction(function(post) {      // correct counter     if(post)     {         // console.log(post);            if(active)         {             // if toggeling on         }         else         {             // if toggeling off         }     }      return post; }) 

when invoking transaction child_added invoked again, giving me duplicate jobs.

is expected behavior? should check see if item has been got before , add array accordingly? or doing wrong?

thanks in advance time

you're hitting interesting edge case in how firebase client handles transactions. transaction function running twice, first on null , on actual data. it's apparent see if listen value events on /jobs, since you'll see:

  1. initial value
  2. null (when transaction starts , runs on null)
  3. initial value again (when transaction runs again on real data)

the null value in step 2 client's initial guess current value. since client doesn't have cached data /jobs (it ignores cached data /jobs/list), guesses null. wrong. unfortunately has been long time, it's unlikely change in current major version of sdk.

and because of null in step 2, you'll child_removed events (which you're not handling right now) , in step 3 you'll child_added events re-add them.

if handled child_removed events, you're items wouldn't end duplicated, still disappear / reappear, isn't desirable. workaround in current setup explicitly tell transaction not run local estimate, can passing in false third parameter:

function transact() {     var path = 'jobs/';     var ref = firebase.database().ref(path);     ref.transaction(function(post) {       return post;     }, function(error, committed, snapshot) {        if (error) {         console.log('transaction failed abnormally!', error);       } else if (!committed) {         console.log('transaction aborted.');       } else {         console.log('transaction completed.');       }     }, false); } 

i'm sorry don't have better solution. said: it's unlikely we'll able change behavior in current generation of sdks.


Comments

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -