Javascript Firebase Web SDK-导致在(';子项)上添加(';,func.)以调用的事务

Javascript Firebase Web SDK-导致在(';子项)上添加(';,func.)以调用的事务,javascript,firebase,firebase-realtime-database,Javascript,Firebase,Firebase Realtime Database,请参见jsbin.com/ceyiqi/edit?html,控制台,输出以获取可验证的示例 我有一个参考听一个数据库点 作业//list 其中是团队的唯一编号 在此入口点下是作业列表 在这一点上,我有一个听众 this.jobsRef.orderByChild('archived') .equalTo(false) .on('child_added', function(data) { 我还有一个方法可以执行以下事

请参见jsbin.com/ceyiqi/edit?html,控制台,输出以获取可验证的示例

我有一个参考听一个数据库点

作业/
/list

其中
是团队的唯一编号

在此入口点下是作业列表

在这一点上,我有一个听众

this.jobsRef.orderByChild('archived')
                    .equalTo(false)
                    .on('child_added', function(data) {
我还有一个方法可以执行以下事务:

ref.transaction(function(post) {

    // correct the counter
    if(post)
    {
        // console.log(post);   
        if(active)
        {
            // if toggeling on
        }
        else
        {
            // if toggeling off
        }
    }

    return post;
})
调用事务时,添加的
子项也会再次被调用,给我重复的作业

这是预期的行为吗? 我是否应该简单地检查该项之前是否已获得并相应地添加到数组中? 还是我做错了什么


提前感谢您的时间

您在Firebase客户端如何处理事务方面遇到了一个有趣的边缘案例。您的事务函数运行了两次,首先是在
null上,然后是在实际数据上。很明显,您可以查看是否在/jobs上侦听
value
事件,从那时起,您将看到:

  • 初始值
  • null(当事务开始并在
    null
    上运行时)
  • 再次初始值(当事务在真实数据上再次运行时)
  • 步骤2中的
    null
    值是客户端对当前值的初始猜测。由于客户端没有/jobs的缓存数据(它忽略/jobs/list的缓存数据),它猜测为空。这显然是错误的。但不幸的是,这种情况已经持续了很长时间,因此在当前SDK的主要版本中不太可能更改

    由于步骤2中的
    null
    ,您将删除
    child\u
    事件(您现在没有处理这些事件),然后在步骤3中,您将添加
    child\u
    事件以重新添加它们

    如果您处理了
    child\u removed
    事件,您的项目不会重复,但它们仍然会消失/重新出现,这可能是不可取的。当前设置中的另一个解决方法是明确告诉事务不要使用本地估计值运行,您可以通过将
    false
    作为第三方传入来完成d参数:

    function transact() {
        var path = 'jobs/';
        var ref = firebase.database().ref(path);
        ref.transaction(function(post) {
          return post;
        }, function(error, committed, snapshot) { 
          if (error) {
            console.log('Transaction failed abnormally!', error);
          } else if (!committed) {
            console.log('Transaction aborted.');
          } else {
            console.log('Transaction completed.');
          }
        }, false);
    }
    

    很抱歉,我没有更好的解决方案。但正如我所说:我们不太可能在当前一代SDK中改变这种行为。

    我不太清楚您看到的行为。您能给出一个更好的解决方案吗?更好的是一个(附加的)链接到重现问题的jsbin/JSFIDLE,以便我们可以看到它的运行。调用事务是否会导致任何侦听器再次运行?即使在事务中没有更改任何数据,我认为这是可能的。就像您如何使用.on(child_添加)一样要在不更改数据的情况下检索数据。@Frank van Puffelen如何在不使用我的一个项目的数据库的情况下将jsbin与firebase一起使用?创建一个单独的项目进行测试。我使用
    https://stackoverflow.firebaseio.com
    用于我的大多数测试,并免费共享apikey/url。