0

I'm seeking something where I can thread through multiple updates to multiple firebase.database.References (before performing a commit) a single object and then commit that at the end and if it is unsuccessful no changes are made to any of my Firebase References.

Does this exist? the firebase.database.Transaction I thought would be similar since it is an atomic update and it does involve a callback which says if it has been committed or not, but the update function, I believe, is only for a single object, and the function doesn't seem to return a transactionId or something I could pass to other firebase.database.Transactionss or something.

UPDATE This transaction's update seems to return a Transaction which would lend itself to perhaps chaining: https://firebase.google.com/docs/reference/js/firebase.firestore.Transaction

however this is different from the other Transaction:

Thalatta
  • 4,510
  • 10
  • 48
  • 79

1 Answers1

1

Firebase Database transactions perform an update to a single location based on the current value of that same location. They explicitly do not work across multiple locations, since that would limit their scalability. Sometimes developers work around this by performing a transaction higher up in their JSON tree (at the first common point of the locations). I'd recommend against that, as that would limit the scalability even further.

The only way to efficiently update multiple locations with one API call, is with a multiple location update. This does however not have reading of the current value built-in.

So if you want to update multiple locations based on their current value, you'll have to perform the read operation in your application code, turn that into a multi-location update, and then use security rules to ensure all of those updates follow your application rules. This is a quite non-trivial approach, so I hardly see it being done in practice. See my answer here for an example: Is the way the Firebase database quickstart handles counts secure?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • if you make a transaction higher up in the tree, is this not recommended in terms of scalabilitly because there is more of the graph that it would have to traverse to make sure a concurrent update wasn't effecting / more chances for it to have to rerun because of that fact? – Thalatta Jun 20 '18 at 16:03
  • 1
    Yeah, there's just much more likely to be contention. If there is no contention it is cheap of course. This is one of the reasons you might want to offload the transaction to a server (or Cloud Functions). If these writes happen from one place, there is less contention. But if the updates are "all over the tree" then client-side writes might still conflict, and cause retries. So it typically works best if you isolate the data that you need to transactionally update. – Frank van Puffelen Jun 20 '18 at 16:15
  • in the "multi-location" update case, assuming the datastructure was on two children of the application's parent node, would involve doing `.once("value")` on both children in a nested fashion and then making one fell swoop of an `update` on the database `ref`? – Thalatta Jun 20 '18 at 18:37