I'm making an app for an (imaginary) massage center. In an activity, the user can click a button to make a reservation. Only one customer must be able to make a reservation for a specific date and time, so I have to use a transaction that takes into account the current state of the database to handle the update.
Right now, I am doing the following:
public void processViewResult(Object object, String tag) {
if (tag.equals("reservation")) {
final Reservation reservation = (Reservation) object;
database.getReference().runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
MutableData freeSlots = mutableData.child("slots").child(reservation.getDate());
MutableData userReservations = mutableData.child("users")
.child(reservation.getUserId()).child("reservations");
Boolean isSlotAvailable = freeSlots.hasChild(reservation.getHour());
if (isSlotAvailable) {
mutableData.child(reservation.getHour()).setValue(null);
userReservations.child(String.valueOf(reservation.hashCode())).setValue(reservation);
return Transaction.success(mutableData);
} else {
return Transaction.abort();
}
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
if (databaseError != null) {
Log.e(this.getClass().getSimpleName(), databaseError.toString());
} else {
Log.e(this.getClass().getSimpleName(), "Updated successfully");
}
}
});
}
}
There is several problems with this approach:
1) Since I need to update both the time slots available and the reservations made for the current customer, I need to get a snapshot of the whole database. If the application scaled, this would be very inefficient.
2) This approach has a lot of boilerplate.
Can you please tell me if there is a simpler and more elegant solution to this?