Say I have a project with a "users" node and a "pets" node. When a user gets a pet, I want to both add the pet's key to the user's "pets" node and the user id to the pet's "owner" node.
Example:
{
"users":{
"user1":{
"pets":{
"pet1":true,
"pet3":true
}
...
}
},
"pets":{
"pet1":{
"owner":"user1",
...
},
...
}
}
I want to make sure both updates succeed to prevent an inconsistent state.
I read about how to work with Firebase transactions here, however when I try to create a transaction that modifies the relevant values (using dbRef.runTransaction(...)), I get this DatabaseError error:
The transaction had too many retries
The transaction only seems to work when I call runTransaction() on the specific node I modify (for example, calling
dbRef.child("users").child("user1").runTransaction(...));
However, this does not help me because I need to reach both the relevant user and the pet. How can I make this transaction work?
According to Firebase Docs, you don't need the use of a Transaction Operation (i'll explain this later).
In order to save data in multiple nodes at ONE PACKET, I advise you to build a Map<> array in which the Key represents the path, and the Value represents, well, whatever you want to store inside.
Lets say "user1" just became the owner of "pet4", and your dbRereference is pointing on the root directory:
FirebaseDatabase dbRef = FirebaseDatabase.getInstance().getReference();
Map<String, Object> update = new HashMap<>();
update.put("users/user1/pets/pet4", true);
update.put("pets/pet4/owner", "user4");
Later you can run the .updateChildren(Map<,>) and attach a listener.
dbRef.updateChildren(update).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful())
Log.d("Success!");
else
Log.d("Failure");
}
});
In this way if a failure occurrs, your database won't be changed at all.
"Transaction" is a term that Firebase gave for a different operation, which I believe was the cause of your confusion: It is used when working with data that could be corrupted by concurrent modifications, such as incremental counters. For further read, open the link attached at the beginning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With