简体   繁体   中英

Firebase Web Transactions applyLocally not suppressing initial local events

So since I've started using Firebase Web Transactions within the Firebase Cloud Functions environment I haven't been able to have the third parameter 'applyLocally' work correctly. I've been setting it to false to suppress getting the initial null value incase the data that is gotten from the transaction is actually null itself. When I run the code after deploying it, it passes null to the update function, but when I run the code again without a new deploy to Cloud Functions, THEN it suppresses all local events and I only see my data.

Q: Is the transaction parameter 'applyLocally' set to false supposed to suppress locally cached values every time when applyLocally is set to false, or is it built so that after the initial code deploy you will get null as a value passed to the update function?

The reason why I'm asking this question is because if the locally cached values aren't suppressed every time, then I would have to account for that initial intermediate state, whereas then I don't understand why I should use applyLocally at all. Also because I didn't see anything elaborating within the docs.

The docs I've read through are: https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction

https://firebase.google.com/docs/database/web/read-and-write#save_data_as_transactions

I've also come across a similar question with a seemingly accurate answer, but the question and answer are over 4 years old (not sure if outdated), and the link to old docs doesn't provide anything the current docs don't.

Firebase transactions in NodeJS always running 3 times?

Here is my code that duplicates this error in my environment:

workerDataRef.transaction(firstTransactionUpdater,firstTransactionOnComplete,false);
  function firstTransactionUpdater(workerData){
    console.log(`Transaction checker Function Running. Worker Data is `,workerData);
    if(workerData === null){ //data should not be null
      console.log("100 Data was null");
      return workerData;
    }
    else{ //workerData is not null
      //DO WORK
      console.log("200 Data was not null");
      return workerData;
    }
  }
  function firstTransactionOnComplete(error, committed, snapshot) {
    if (error) { //error thrown
      throw new Error(error);
    } else if (!committed) { //transaction aborted
      console.log(`Transaction checker aborted!`);
    } else { //transaction completed successfully
      console.log("Continuing on with next process");
    }
  }

And here are the logs that this code block reproduces from being run twice after one deploy to Cloud Functions:

1:35:40.495 PM Function execution took 410 ms, finished with status: ok 
1:35:40.494 PM Continuing on with next process  
1:35:40.489 PM 200 Data was not null  
1:35:40.489 PM Transaction checker 2 Function Running. Worker Data is {    
//... } 
1:35:40.400 PM 100 Data was null  
1:35:40.399 PM Transaction checker 2 Function Running. Worker Data is null  
1:35:40.190 PM Function execution started  

1:34:35.386 PM Continuing on with next process  
1:34:33.985 PM 200 Data was not null  
1:34:33.885 PM Transaction checker 1 Function Running. Worker Data is { //.. 
}
1:34:25.698 PM Function execution took 623 ms, finished with status: ok 
1:34:25.504 PM 100 Data was null  
1:34:25.499 PM Transaction checker 1 Function Running. Worker Data is null  
1:34:25.076 PM Function execution started  

UPDATE

*In running and trying to duplicate the event data being null only after the initial deploy I found I was wrong. The locally cached data is just being passed as null at inconsistent times. Running the transaction several times after a single deploy with the 'applyLocally' set to false still passes null, and sometimes doesn't.

Is the transaction parameter 'applyLocally' set to false supposed to suppress locally cached values...?

No, that is not the purpose of the applyLocally parameter. The reference documentation says it best:

By default, events are raised each time the transaction update function runs . So if it is run multiple times, you may see intermediate states. You can set this to false to suppress these intermediate states and instead wait until the transaction has completed before events are raised.

Setting applyLocally to false doesn't fundamentally change how transactions behave on the wire. It only changes when the client/SDK raises events.

By default the client raises events as soon as it can, and then raises reconciliatory events if needed. When you set applyLocally to false , the client will only raise events after it receives acknowledgement from the server that its data was committed.

Also see my answer here for an explanation of how transactions run. The default behavior is that the Firebase client will raise events after step 2, which can happen multiple times. Setting applyLocally to false causes events to only be raised after step 4, after the server acknowledges that the value was written.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM