javascript - Firebase Web SDK - 事务导致 ('child_added' 、 func.. 被调用

标签 javascript firebase firebase-realtime-database

请参阅 jsbin.com/ceyiqi/edit?html,console,output 以获取可验证的示例。

我有一个监听数据库点的引用

工作/<key>/列表

哪里<key>是团队的唯一编号

在此入口点下是一个作业列表

我有一个听众在这一点上

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;
})

调用事务时 child_added也再次被调用,给我重复的工作。

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

预先感谢您的宝贵时间

最佳答案

您在 Firebase 客户端处理事务的方式中遇到了一个有趣的边缘情况。您的事务函数运行两次,第一次在 null 上运行,然后在实际数据上运行。很明显,如果您监听/jobs 上的 value 事件,那么您将看到:

  1. 初始值
  2. null(当事务启动并在 null 上运行时)
  3. 再次初始值(当交易在真实数据上再次运行时)

步骤 2 中的 null 值是客户端对当前值的初始猜测。由于客户端没有/jobs 的缓存数据(它忽略/jobs/list 的缓存数据),因此猜测为 null。这显然是错误的。但不幸的是这种情况已经存在很长时间了,因此在当前的 SDK 大版本中不太可能改变。

由于第 2 步中的 null,您将收到 child_removed 事件(您现在没有处理该事件),然后在第 3 步中您将获取 child_added 事件来重新添加它们。

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

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 中改变这种行为。

关于javascript - Firebase Web SDK - 事务导致 ('child_added' 、 func.. 被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39110154/

相关文章:

node.js - Firebase verifySessionCookie() 导致应用程序在部署到 Firebase 时超时,但在本地工作正常

javascript - 无法读取未定义的 React-Native Firebase React-native-fetch-blob 的属性 'DocumentDir'

java - 如何使 addListenerForSingleValueEvent 在循环中工作?

java - Firebase 在类上找不到要序列化的属性

javascript - 如何在javascript中处理xml数据

javascript - JQUERY 显示和隐藏无法正常工作

javascript - 是否可以从 webpack 源映射中删除 "sourcesContent"?

javascript - 异步 npm 模块中仅错误回调

javascript - AngularFire2 - 如何在页面刷新后保持登录状态

firebase-realtime-database - Firebase 数据库规则 : Checking for service account credentials