'Realtime Database Firebase "All or nothing" transactions
Is there a way to manipulate the transactions API in the RTDB for "batch" writes?(We currently can't migrate to Firestore)
Our problem is as follows:
When writing a new "Job" object to the server we are preforming three consecuteve writes:
- Writing the location key using the GeoFire API
- Writing the job
- Connecting the Job ID to the user created it
Unfortunately, if one of the writes fails but a previous one succeeded, it causes major bugs in the system.
We are looking for ways to ensure the completeness, or reverting the operation if one of the writes fails.
Solution 1:[1]
If it is just a matter of writing and "ensuring the completeness, or reverting the operation if one of the writes fails", you can use a simultaneous update by using the update() method.
As detailed in the documentation, "simultaneous updates .... are atomic: either all updates succeed or all updates fail.". See this part of the documentation: https://firebase.google.com/docs/database/web/read-and-write#update_specific_fields
Note that the Real Time Database also offers the possibility to save data as transactions, see the documentation items here and here. But probably, in your case, using simultaneous updates will be sufficient.
Solution 2:[2]
Here is a snippet from my code just for future references. (Used Renaud's answer)
private void pushJob(Person person) {
DatabaseReference dataBase = FirebaseDatabase.getInstance().getReference();
GeoHash geoHash = new GeoHash(new GeoLocation(choosenLatLng.latitude,choosenLatLng.longitude));
Map<String, Object> geofireData = new HashMap<>();
geofireData.put("g", geoHash.getGeoHashString());
geofireData.put("l", Arrays.asList(choosenLatLng.latitude,choosenLatLng.longitude));
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/Geofire/" + job.getmJobUid(), geofireData);
childUpdates.put("/Jobs/" + job.getmJobUid(), job);
childUpdates.put("/Users/" + job.getPersonUid(), person);
dataBase.updateChildren(childUpdates).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
progressDialog.dismiss();
updateUI();
}
});
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | M0ngi |
