从Firebase中的引用正确使用hasChild()和forEach()?

时间:2012-07-10 19:39:07

标签: firebase

由于我的理解和SQL背景有限,我不太习惯使用hasChild()和forEach();他们觉得他们属于参考而不是快照。

(我将在其余的讨论中使用hasChild(),但这些概念是可以互换的。)

这是我的推理:

  1. 我为用户表调用了Firebase路径,比如appname/users
  2. 我想查看用户(Fred)是否存在
  3. 我获得了一个参考:var users = new Firebase('appname/users')
  4. 但我无法确定这里是否有孩子。所以这就是我现在所拥有的:

    users.child('Fred').once('value', function(snapshot) {
       /** waits around forever if Fred doesn't exist */
    });
    

    但这不太有用。所以现在我必须通过这样的方式获得用户的价值(感觉有点反直觉,因为我对用户不感兴趣):

    var users = new Firebase('http://.../appname/users');
    users.once('value', function(snapshot) { 
          snapshot.childExists('Fred', function(exists) { 
             /* do something here*/ 
          }); 
       });
    

    我不认为基于文档提取appname/users会产生很大的开销,但如果我只是想确定密钥'Fred'是否存在,这就像是一个难看的代码。< / p>

    我希望看到类似的内容:

    var users = new Firebase('http://.../appname/users');
    users.hasChild('Fred', function(exists[, snapshotOfFred]) { 
       /* do something here*/ 
    });
    

    使用forEach / hasChild有更好的方法吗?我在这里错过了任何重要的逻辑考虑因素吗?

1 个答案:

答案 0 :(得分:12)

您实际上是在第一个代码段的正确轨道上。无论Fred是否已存在,.once()都会使用快照触发回调。所以你可以这样做:

users.child('Fred').once('value', function(snapshot) {
   if (snapshot.val() === null) {
       /* There is no user 'Fred'! */
   } else {
       /* User 'Fred' exists.
   }
});

您的第二个代码段 实际上会产生很大的开销,因为Firebase会从Firebase获取整个“用户”位置,如果您有1000个用户,这可能会非常大!因此,第一个代码片段绝对是可行的方法。

hasChild和forEach位于DataSnapshot上而不是Firebase上的原因是它们可以同步。在我们早期的API测试中,我们在Firebase引用中提供了混合使用的同步和异步方法,但我们发现这对于人们来说是一个重要的绊脚石(如果人们看到hasChild方法,他们会期望它返回一个布尔值立即)。所以我们创建了.on()和.once()作为Firebase上唯一的异步回调方法。 Firebase引用上的其他所有内容都是同步的(尽管我们有时会提供可选的异步完成回调),并且DataSnapshot上的所有内容都是100%同步的。

因此,我们的目标是让Firebase的异步特性更易于理解和使用!但也许我们没有100%成功。 :-)我们会在计划未来的API调整时考虑您的反馈。谢谢!