Skip to content
Advertisement

Firebase how to break realtime database transaction with different state/message if different condition is true?

is it a good practice at all and if yes what is the correct way to break a transaction with different error states/messages for different situations?

I have a transaction running over an ‘offer’ entry doing ‘seats’ reservation:

I want to break it if one of the following 3 conditions is true and return state/message to the caller function.

  1. if the asking user already made a reservation of seats of this offer.
  2. if there is not enought seats.
  3. if this offer does not exists.

And if everything is ok the transaction should complete normally and return state/message to the caller function that reservation is made.

I’m not sure how to break the transaction in case of one of the conditions is true.

  • if I use throw new Error(‘description of the problem.’) then this will be an Exception and it’s not handled by catch() handler of the transaction Promise and I’m not sure how to handle this exception because it’s an asynchronous function here. so I think i should not use an exception.

Here is what I mean:

JavaScript

here is my data in realtime database:

JavaScript

here is my test data sent by Postman:

JavaScript

==== updated with final source ====

many thanks to Renaud Tarnec!

So here is my final source that is working fine. If someone sees a potential problem please let me know. Thanks.

JavaScript

The only pain is a warning during deploy in VSCode terminal about this abortions by returning no value:

JavaScript

currently I’m not sure if I could do anything about it.

Advertisement

Answer

Look at this doc in the Firebase API Reference documentation: https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction

Below is the code from this doc. Look how return; is used to abort the transaction (The doc also says: “you abort the transaction by not returning a value from your update function”). And note how this specific case is handled in the onComplete() callback function that is called when the transaction completes (within else if (!committed){} ).

JavaScript

So IMHO you should adopt the same pattern and at the places in your code where you ask “**? how to break the transaction” you do return;.

Update: You can differentiate the abortion cases by using a variable, as follows. If you add, via the Firebase console, a node age with value > 20 to users.ada.name, the first abortion cause will be “triggered”.

JavaScript

If I am not mistaking, you could also do that with promises, as you do in your code. The doc says that the transaction returns a non-null firebase.Promise containing {committed: boolean, snapshot: nullable firebase.database.DataSnapshot} and explains that this promise “can optionally be used instead of the onComplete callback to handle success and failure”.

So by:

  1. Doing return; for your two cases of abortion, and
  2. Reading the value of the committed boolean

you should be able to handle the abortion cases in your code by doing

JavaScript

I have not tested this approach however

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement