Firebase транзакции, изменяющие два или более значения дочерних узлов одновременно - PullRequest
0 голосов
/ 04 июня 2018

Итак, у меня есть простая система бронирования, где я позволяю пользователям бронировать билеты с помощью Firebase.Я использую транзакции, чтобы избежать проблем параллелизма.

По сути, это структура БД:

TerminalID:
    BussID:
       SeatID:
           TempEmail:

Так что это пример, где я хочу забронировать места для автобуса № 1.seatList - это список мест с идентификаторами сидений, которые пользователь хочет забронировать.И для резервирования бронирования я добавляю временное электронное письмо к идентификатору места.

DatabaseReference postRef = mDatabase.child("terminal").child("1");
postRef.runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        if(mutableData.getValue() == null){
            return Transaction.success(mutableData);
        }
        for (int i = 0; i < seatList.size(); i++) {
            if (mutableData.child(Integer.toString(seatList.get(i))).child("tempEmail").getValue() == null) {
                mutableData.child(Integer.toString(seatList.get(i))).child("tempEmail").setValue(mUser.getEmail());
            }
            else{
                Transaction.abort();
            }
        }

        return Transaction.success(mutableData);
    }

    @Override
    public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
        progressBar.setVisibility(View.INVISIBLE);

        // Transaction completed
        if (b == true){                                                         
            Toast.makeText(getContext(), "Success!",
            Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(getContext(), "Someone just reserved them!", Toast.LENGTH_SHORT).show();
        }
    }
});

Правила:

"terminal": {
  ".read": true,
  //".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
  "$bid": {
    "$sid": {
      "uid": {
        ".write": "data.val() === 'null' || data.val() === auth.id"
      },
      "tempEmail": {
        ".write": "auth != null"
      },
      "booked": {
        ".write": false
      },
      "email": {
        ".write": false
      }
    }
  }
},

Однако я получаю сообщение об ошибке отказа в разрешении.Я дважды проверил правила и позволил любому писать, чтобы убедиться, что это не правила.Я подозреваю, что это потому, что я пытаюсь обновить более одного дочернего узла?Однако я также попытался забронировать только 1 место, и эта ошибка все еще происходит.Поэтому я думаю, что это может быть потому, что я пытаюсь установить значение дочернего узла, что, возможно, недопустимо.Или, возможно, что-то не так с моим кодом в целом?

РЕДАКТИРОВАТЬ: я допустил ошибку, она работает, когда я устанавливаю write = true на вершину JsonObject.

...