Как правильно использовать транзакции в firebase с Angular - PullRequest
0 голосов
/ 27 ноября 2018

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

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

Вот мой код:

saveSeats(key, numbers){
  for (let i = 0; i < numbers.length; i++) {
    const num = numbers[i].toString();
    const objPath = `${this.basePath}/${key}/${num}`;      
    const busesRef = firebase.database().ref("buses/"+key+"/"+num); 

    busesRef.transaction(function(currentValue) {
      if (currentValue === null) {
        let newRow = JSON.stringify({ number: num, status: "reserved", timestamp: Date.now() });
        busesRef.child("0").set(newRow);
      } else {
        console.log('Value Already Exists');
      }    
    }, function(error, committed, snapshot) {
      if (error) {
        console.log('Transaction failed abnormally!', error);
      }else if (!committed) {
        console.log('We aborted the transaction (because number already exists).');
      } else {
        console.log('Number added!');
      }
      console.log("Number: ", snapshot.val());      
    });

  }

}

1 Ответ

0 голосов
/ 27 ноября 2018

Вы не должны использовать метод set() в своей транзакции, как представлено в doc :

Примечание: изменение данных с помощью set () отменит все отложенные транзакциив этом месте, поэтому следует соблюдать особую осторожность, если смешивать set () и транзакцию () для обновления одних и тех же данных.

Вы должны "передать transaction() функцию обновления, которая используется для преобразованиятекущее значение в новое значение. "

Таким образом, обычно должно работать следующее:

  busesRef.transaction(function(currentValue) {
    if (currentValue === null) {
      let newRow = JSON.stringify({ number: num, status: "reserved", timestamp: Date.now() });
      return newRow;  // <- Here the function returns the new value
    } else {
      console.log('Value Already Exists');
      return; // Will abort the transaction.
    }    
  },
  ....

Наконец, я думаю, что вам не нужно структурировать ваш объект.Выполнение следующих действий должно работать:

      let newRow = { number: num, status: "reserved", timestamp: Date.now() };
      return newRow;

или, конечно, просто

      return { number: num, status: "reserved", timestamp: Date.now() };

Еще одно соображение:

IВы заметили, что вы заключаете транзакции в цикл for, что означает, что вы будете изменять значения различных узлов busesRef.Разве вы не должны делать все эти изменения в одной транзакции?И не с набором «атомарных» транзакций, каждая из которых изменяет значение данного busesRef узла?Это зависит от вашего конкретного случая использования.

...