Одновременное бронирование временного интервала в базе данных Firebase Real Time (проблема перезаписи)

Попробуйте

let toRight = CGRect(x: width, y: 0, width: 0, height: height)
scrollView.scrollRectToVisible(toRight)
0
задан Mena 30 March 2019 в 22:37
поделиться

1 ответ

Ваш код, кажется, предполагает, что запуск транзакций дает вам блокировку местоположения, но это не так, как работают транзакции в Firebase. Вместо этого транзакции в Firebase работают с логикой сравнения и установки: клиент сообщает вам, каково (по его мнению) текущее значение, и вы сообщаете ему, что в этом случае становится новым значением, возвращая это новое значение.

Таким образом, вместо того, чтобы звонить .setValue(s) на месте, вы должны вернуть s в MutableData:

dbRef.child(String.valueOf(selectedDate.getTime())).runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        BookingSlot s = mutableData.getValue(BookingSlot.class);
        if (s == null) {
            mutableData.setValue(uid); // TODO: pass in the UID of the user who's claiming this slot
            return Transaction.success(mutableData);
        } else {
            Toast.makeText(BookingActivity.this,"Slot has just been booked!",Toast.LENGTH_LONG).show();
            return Transaction.abort();
        }
    }

    @Override
    public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
        Log.e("Booking", "postTransaction:onComplete:" + databaseError);
    }
});

С помощью приведенного выше кода клиенты не будут перезаписывать каждый другие ценят.

Но с Firebase вы всегда должны учитывать, что злоумышленник может написать свой собственный код для вашей базы данных, поскольку он может найти данные конфигурации в APK вашего приложения. Поэтому в правилах безопасности Firebase на стороне сервера вы также должны указывать, что на каждый слот можно претендовать только один раз.

Если заказы хранятся в соответствии с /bookings, это можно сделать с помощью чего-то вроде:

{
  "rules": {
    "bookings": {
      "$timeslot": {
        ".write": "data.val() === null || data.val() === auth.uid"
      }
    }
  }
}

Это позволяет производить запись, если либо еще нет значения (слот не имеет было заявлено), или если пользователь пишет тот, кто требовал слот ранее (что позволило бы им очистить слот).

0
ответ дан Frank van Puffelen 30 March 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: