在Angular的Firebase中使用事务的正确方法是什么

时间:2018-11-27 16:13:27

标签: angular firebase firebase-realtime-database angularfire2 angular7

在使用Firebase时,我通常使用AngularFire2。但是这次我没有,我使用了普通的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 :(得分:1)

您不应在交易中使用doc所示的set()方法:

  

注意:使用set()修改数据将取消所有未决的事务   在该位置,因此如果将set()和   transaction()更新相同的数据。

您应该“通过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() };

进一步的考虑:

我注意到您将事务封装在for循环中,这意味着您将修改不同busesRef节点的值。您不应该在一次交易中进行所有这些修改吗?而不是通过一组“原子”事务,每个事务都会修改给定busesRef节点的值?这取决于您的确切用例。