Firebase 事务中的数据为空

Firebase 事务中的数据为空,firebase,Firebase,我对交易有问题。事务中的数据始终为null,并且只调用一次更新处理程序。报告说: 要实现这一点,需要向transaction()传递一个更新函数 用于将当前值转换为新值。如果另一个 在成功创建新值之前,客户端将写入该位置 写入时,将使用新的 当前值,将重试写入。这将发生 重复执行,直到写入成功且没有冲突或中止 通过不从更新函数返回值进行事务处理 现在我知道现在没有其他客户端访问该位置。其次,如果我正确阅读了文档,那么如果无法检索和更新数据,则应该多次调用updateCounters函数 另一件事

我对交易有问题。事务中的数据始终为null,并且只调用一次更新处理程序。报告说:

要实现这一点,需要向transaction()传递一个更新函数 用于将当前值转换为新值。如果另一个 在成功创建新值之前,客户端将写入该位置 写入时,将使用新的 当前值,将重试写入。这将发生 重复执行,直到写入成功且没有冲突或中止 通过不从更新函数返回值进行事务处理

现在我知道现在没有其他客户端访问该位置。其次,如果我正确阅读了文档,那么如果无法检索和更新数据,则应该多次调用updateCounters函数

另一件事-如果我去掉条件
if(counters==null)
执行将失败,因为计数器为
null
,但在后续尝试中,事务会很好地完成-检索数据并进行更新

简单的
一次设置
在这个位置可以正常工作,但不安全

请问我错过了什么

这是密码

self.myRef.child('counters')
  .transaction(function updateCounters(counters){
    if (counters === null) {
      return;
    }
    else {
      console.log('in transaction counters:', counters);
      counters.comments = counters.comments + 1;
      return counters;
    }
  }, function(error, committed, ss){
    if (error) {
      console.log('transaction aborted');
      // TODO error handling
    } else if (!committed){
      console.log('counters are null - why?');
    } else {
      console.log('counter increased',ss.val());
    }
  }, true);
这是位置中的数据

counters:{
  comments: 1,
  alerts: 3,
  ...
}

通过在
if(…==null)
块中返回
undefined
,您正在中止事务。因此,它从不向服务器发送尝试,从不意识到本地缓存的值与远程缓存的值不同,也从不使用更新的值(来自服务器的实际值)重试

这可以通过以下事实得到证实:
committed
false
,并且成功函数中的错误为
null
,如果事务中止,则会发生此错误

交易工作如下:

  • 将本地缓存的值传递到处理函数中,如果从未从服务器获取此数据,则本地缓存的值为
    null
    (该路径最可能的远程值)
  • 从处理函数获取返回值,如果该值
    未定义
    则中止事务,否则,创建当前值(null)的散列,并将其和新值(由处理函数返回)传递给服务器
  • 如果本地哈希与服务器的当前哈希匹配,则应用更改,服务器返回成功结果
  • 如果未应用服务器事务,则服务器返回新值,然后客户端使用服务器中的更新值再次调用处理函数,直到成功
  • 当最终成功且发生不可恢复的错误时,或者事务被中止(通过从处理函数返回undefined),则调用success方法并给出结果
因此,为了实现这一点,显然不能对第一个返回值中止事务


实现相同结果的一个解决方法是将事务包装在
一次('value',…)
回调中,尽管它是耦合的,性能不如设计的那样好,也不适合使用事务,这将确保在运行事务之前将其缓存在本地。

感谢您对事务的非常清晰的解释!!令人惊叹的!这应该放在文件里,我很确定文件里有。如果您觉得他们需要更多的强调,我强烈建议您在任何您认为应该显示详细信息的页面上使用“发送反馈”按钮:)