如何使用 .hasChild 并使用 Firebase 检索 child?

How to use .hasChild and retrieve child using Firebase?

我正在开发一个具有以下 Firebase 结构的项目:

user {
  score: 0,
  messages : {
    key1 { name: name, text: text }
    key2 { name: name, text: text }
    key...
  }
}

我目前有两个问题。第一个是确定用户是否有 "messages" child,如果没有,则给它一个(连同分数),这是我到目前为止想出的代码:

  ref.once('value', function (snapshot) {
    if (!snapshot.hasChild("messages")) {
        ref.set({
            score: 0,
            messages: 0
        });
    }
});

下一步是检索并显示来自 child 的消息,一旦数据被推送到它,如下所示:

ref.child("messages").on('child_added', function (snapshot) {
    var message = snapshot.val();
    $('#messagesDiv').prepend(message.text ": " + message.name);
});

但这似乎也不起作用。

这是我做的fiddle

希望大家帮我解决这个问题!语法看起来正确,我阅读了文档以找到大部分当前代码。

提前致谢!

设置初始数据

你的带有 hasChild 的代码似乎执行得很好。它只是没有多大意义。您添加的结构导致:

user {
  score: 0,
  messages: 0
}

这与您在问题中绘制的结构不同:messages 这里只是一个数字,而您希望它是消息的集合。此外,此更改 不会 触发您的 child_added 处理程序,因为...您不会向 messages.

添加子项

您从设计数据结构开始就做对了。下一步是确保您坚持使用该数据结构。因此,如果您想添加初始消息,请以正确的结构添加消息:

ref.once('value', function (snapshot) {
    if (!snapshot.hasChild("messages")) {
        ref.set({
            score: 0,
            messages: { 0: { name: 'puf', text: 'welcome' }}
        });
    }
});

如果您修改 fiddle,您会看到 welcome 消息确实显示在您的 #messagesDiv 中。

我认为这种方法仍然存在缺陷。除非您真的想添加欢迎消息,否则无需添加 messages 节点。我只是将 score 设置为 0,一旦用户输入第一条消息,就会添加 messages 节点:

ref.once('value', function (snapshot) {
    if (!snapshot.hasChild("messages")) {
        ref.set({ score: 0 });
    }
});

正在添加新消息

我注意到您的 fiddle 中也有以下代码:

$('#messageInput').keypress(function (e) {
    if (e.keyCode == 13) {
        var name = user;
        var text = $('#messageInput').val();
        // POST
        ref.child("messages").set({
            name: name,
            text: text
        });
        $('#messageInput').val('');
    }
});

输入处理很好,但是您修改 Firebase 数据结构的代码再次没有遵循您开始提问时使用的数据结构。如果我们执行这段代码,数据结构将是:

user {
  score: 0,
  messages: {
      name: 'NotToBrag',
      text: 'asked 10 hours ago'
  }
}

以防万一:此结构缺少 关键 key1 或您的结构。哦...而且它还覆盖了 welcome 消息。

当您将子节点添加到 Firebase 列表时,您几乎总是希望使用 push:

        ref.child("messages").push({
            name: name,
            text: text
        });

有了那个微小的变化,数据结构就变成了:

user {
  score: 0,
  messages: {
      0: {
          name: 'puf',
          text: 'welcome'
      },
      '-Jh-aFN42nWef-FvgcfS': {
          name: 'NotToBrag',
          text: 'asked 10 hours ago'
      }
  }
}

所有这些(和往常一样)都是非常小的变化。但他们一起确保你的场景被严重破坏。我用来解决问题的技巧非常基础,您最好将它们添加到您的武器库并学习使用它们。

调试技巧 1:console.log 数据结构

每当我第一次得到某人问题的 MCVE 时,我会立即记录他们的数据结构:

new Firebase('https://your.firebaseio.com/').once('value', function(s) {
  console.log(s.val()); 
})

有时我可能会将 JSON:

字符串化
new Firebase('https://your.firebaseio.com/').once('value', function(s) {
  console.log(JSON.stringify(s.val())); 
})

例如,最后一个片段是获取用于您的问题的数据结构的好方法。

该代码段只显示一次数据结构,因此每次发生变化时都要 运行保留该代码段。

调试技巧 2:删除数据

您的整个 hasChild 片段似乎旨在为用户设置初始数据结构。为了帮助测试,我经常删除数据:

new Firebase('https://your.firebaseio.com/myName').remove()

然后当您再次 运行 fiddle 时,您可以看到您的 hasChild-using 代码做了什么。

我经常在 fiddle 的开头放置代码以清除(或以其他方式重置)我的测试数据,或者只是 运行 来自浏览器 JavaScript 控制台的片段.