为什么我的Firebase查询返回错误的订单? [英] Why does my Firebase query return the wrong order?

查看:137
本文介绍了为什么我的Firebase查询返回错误的订单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



您好,我正在Firebase中执行一个查询,以检索消息列表:

$ b $ (child_added,函数(快照){
console.log(snapshot.val())
$ pre $ ref.child );
});

上面的查询工作正常。它将按顺序显示消息。



消息包含以下属性/字段:

 < message-id>:{
user-id:< user-id>,
message:This is a sample message,
time:1446534920014

$ / code>

问题

显示信息时,我也需要显示用户的名字。所以我需要添加另外一个查询来检索用户的名字,使用 user-id 字段:

  ref.child(messages)。on(child_added,function(snapshot){
var message = snapshot.val();

// get用户名
ref.child(users)。child(message [user-id])。once(value,function(userSnapshot){
//将结果记录在错误的订单
console.log(message,userSnapshot.val()。name);
}
});

问题是内部查询以错误的顺序返回消息列表为什么?为了按照正确的顺序显示消息,应该采取什么正确的方法? p>

编辑



好的,下面是导出的JSON:

  {
messages:{
-K2FyInlsZqLdHou1QnA:{
message:消息1,
user-id:-K2Fxr1gdxynukjDzcIq
},
-K2 FyOlw13MU9KHB5NQh:{
message:Message 2,
user-id:-K2Fxr1gdxynukjDzcIq
},
-K2Fz2GxPgqGf8uDfK0d:{
message:Message 3,
user-id:-K2Fy3uyw-RNcePo_Pn-
}
},
users:{
-K2Fxr1gdxynukjDzcIq:{
name:John Joe
},
-K2Fy3uyw-RNcePo_Pn-:{
name:Alfred





我的目标是显示消息(按顺序)以及用户的名字。如果我这样做:
$ b $ pre $ ref.child(messages)。on(child_added,function(snapshot){
console.log(snapshot.val());
});

按顺序显示消息,即消息1,消息2,消息3。没有用户名,所以我需要查看用户列表来检索用户的名字,然后显示消息:

  ref (child_added,function(snapshot){
ref.child(users)。child(snapshot.val()[user-id])。once( value,function(userSnapshot){
console.log(snapshot.val(),userSnapshot.val()。name);
});
});

返回包含用户名的消息列表,但问题在于顺序错误:消息2,消息1,消息3

解决方案

消息按您期望的顺序进行检索。您可以通过添加一些额外的日志记录来轻松验证这一点:

  ref.child(messages)。on(child_added,函数(快照){
var message = snapshot.val();
console.log(message.message);

ref.child(users)。child (value,function(userSnapshot){
console.log(message.message +':'+ userSnapshot.val()。name);
} );
});

在我最近的运行中,输出是:

 消息1
消息2
消息3
消息2:John Joe
留言1:John Joe
Message 3:Alfred

前三行是消息的顺序。但是,您然后开始检索每个消息的用户;而这些用户并不一定会按照您所要求的顺序返回。

在网络上使用AJAX时,这是一个非常常见的问题:只要网络流量是涉及的,你的代码的顺序不一定是事情发生的顺序。

解决方案总是相同的:不依赖于你的代码在一个具体的顺序。例如:你很可能想在DOM的某个列表中显示消息。

  var ul = document.getElementById '消息'); 
ref.child(messages)。on(child_added,function(snapshot){
var message = snapshot.val();
var li = document.createElement('li ');
li.id ='msg _'+ snapshot.key();
li.innerText = message.message;
ul.appendChild(li);

ref.child(users)。child(message [user-id])。once(value,function(userSnapshot){
li.innerText = userSnapshot.val()。name + ':'+ li.innerText;
});
});

注意:您可能需要考虑添加用户名缓存。您现在将为每个用户调用每个消息的数据库。这是一个O(n ^ 2)的操作,所以不能很好的与用户数量成比例。

Repro: http://jsbin.com/zofasi/edit?js,console


BACKGROUND

Hello guys, I am performing a query in Firebase that retrieves a list of messages:

ref.child("messages").on("child_added", function(snapshot) {
    console.log(snapshot.val());
});

The above query works fine. It displays the messages in order.

A message contains the following properties/fields:

<message-id>: { 
    user-id: <user-id>,
    message: "This is a sample message",
    time: 1446534920014
}   

PROBLEM

When displaying a message, I also need to display the user's name. So I need to add another query that retrieves the user's name using the user-id field:

ref.child("messages").on("child_added", function(snapshot) {
    var message = snapshot.val();

    // get the user's name
    ref.child("users").child(message["user-id"]).once("value", function(userSnapshot) {
        // logs the results in the wrong order
        console.log(message, userSnapshot.val().name);
    }
});

The problem was the inner query returns the list of messages in the wrong order. Why? And what should be the correct way in order to display the messages in the correct order?

EDIT

Ok here you go. Below is the exported JSON:

{
  "messages" : {
    "-K2FyInlsZqLdHou1QnA" : {
      "message" : "Message 1",
      "user-id" : "-K2Fxr1gdxynukjDzcIq"
    },
    "-K2FyOlw13MU9KHB5NQh" : {
      "message" : "Message 2",
      "user-id" : "-K2Fxr1gdxynukjDzcIq"
    },
    "-K2Fz2GxPgqGf8uDfK0d" : {
      "message" : "Message 3",
      "user-id" : "-K2Fy3uyw-RNcePo_Pn-"
    }
  },
  "users" : {
    "-K2Fxr1gdxynukjDzcIq" : {
      "name" : "John Joe"
    },
    "-K2Fy3uyw-RNcePo_Pn-" : {
      "name" : "Alfred"
    }
  }
}

My goal is just to display the messages (in order) along with the user's name. If I do this:

ref.child("messages").on("child_added", function(snapshot) {
    console.log(snapshot.val());
});

It displays the messages in order, i.e. Message 1, Message 2, Message 3. But I still don't have the user's name so I need to look into the users list to retrieve the user's name before displaying the message:

ref.child("messages").on("child_added", function(snapshot) {
    ref.child("users").child(snapshot.val()["user-id"]).once("value", function(userSnapshot) {
        console.log(snapshot.val(), userSnapshot.val().name);
    });
});

That returns a list of the messages including the user's name, but the problem is it's in the wrong order: Message 2, Message 1, Message 3

解决方案

The messages are retrieved in the order you'd expect. You can easily verify this by adding some additional logging:

ref.child("messages").on("child_added", function(snapshot) {
    var message = snapshot.val();
    console.log(message.message);

    ref.child("users").child(message["user-id"]).once("value", function(userSnapshot) {
        console.log(message.message+': '+userSnapshot.val().name);
    });
});

The output from this on my recent runs has been:

"Message 1"
"Message 2"
"Message 3"
"Message 2: John Joe"
"Message 1: John Joe"
"Message 3: Alfred"

What you see here in the first three lines is that the messages are in order. But you then start retrieving the user for each of the messages; and those users don't necessarily come back in the order you fired/expected them.

This a very common problem when using AJAX on the web: as soon as network traffic is involved, the order of your code is not necessarily the order in which things happen.

The solution is always the same: don't depend on your code executing in a specific order. For example: you most likely want to display the message in a list in the DOM somewhere.

var ul = document.getElementById('messages');
ref.child("messages").on("child_added", function(snapshot) {
    var message = snapshot.val();
    var li = document.createElement('li');
    li.id = 'msg_'+snapshot.key();
    li.innerText = message.message;
    ul.appendChild(li);

    ref.child("users").child(message["user-id"]).once("value", function(userSnapshot) {
        li.innerText = userSnapshot.val().name + ': '+ li.innerText;
    });
});    

Side note: you might want to consider adding a cache of user names. You'll now be calling out to the database for each message, for each user. This is an O(n^2) operation, so does not scale very well with the number of users.

Repro: http://jsbin.com/zofasi/edit?js,console

这篇关于为什么我的Firebase查询返回错误的订单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆