为什么我的 Firebase 查询 return 顺序错误?
Why does my Firebase query return the wrong order?
背景
大家好,我正在 Firebase 中执行一个检索消息列表的查询:
ref.child("messages").on("child_added", function(snapshot) {
console.log(snapshot.val());
});
以上查询工作正常。它按顺序显示消息。
一条消息包含以下内容properties/fields:
<message-id>: {
user-id: <user-id>,
message: "This is a sample message",
time: 1446534920014
}
问题
在显示消息时,我还需要显示用户名。所以我需要添加另一个查询来使用 user-id
字段检索用户名:
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);
}
});
问题是内部查询 returns 消息列表的顺序错误。为什么?为了以正确的顺序显示消息,正确的方法应该是什么?
编辑
好的,给你。下面是导出的 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"
}
}
}
我的目标只是显示消息(按顺序)以及用户名。如果我这样做:
ref.child("messages").on("child_added", function(snapshot) {
console.log(snapshot.val());
});
它按顺序显示消息,即消息 1、消息 2、消息 3。但是我仍然没有用户名,所以我需要在显示消息之前查看用户列表以检索用户名:
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);
});
});
那个 returns 包含用户名的消息列表,但问题是顺序错误:消息 2、消息 1、消息 3
邮件按您期望的顺序检索。您可以通过添加一些额外的日志记录轻松验证这一点:
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);
});
});
我最近运行的结果是:
"Message 1"
"Message 2"
"Message 3"
"Message 2: John Joe"
"Message 1: John Joe"
"Message 3: Alfred"
您在前三行中看到的是消息是有序的。但是您随后开始为每条消息检索用户;这些用户不一定会按照您 fired/expected 他们的顺序回来。
在 Web 上使用 AJAX 时,这是一个非常常见的问题:一旦涉及网络流量,代码的顺序就不一定是事情发生的顺序。
解决方案始终相同:不要依赖于您的代码以特定顺序执行。例如:您很可能希望在 DOM 某处的列表中显示消息。
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;
});
});
旁注:您可能需要考虑添加用户名缓存。您现在将为每个用户的每条消息调出数据库。这是一个 O(n^2) 操作,因此不能很好地扩展用户数量。
背景
大家好,我正在 Firebase 中执行一个检索消息列表的查询:
ref.child("messages").on("child_added", function(snapshot) {
console.log(snapshot.val());
});
以上查询工作正常。它按顺序显示消息。
一条消息包含以下内容properties/fields:
<message-id>: {
user-id: <user-id>,
message: "This is a sample message",
time: 1446534920014
}
问题
在显示消息时,我还需要显示用户名。所以我需要添加另一个查询来使用 user-id
字段检索用户名:
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);
}
});
问题是内部查询 returns 消息列表的顺序错误。为什么?为了以正确的顺序显示消息,正确的方法应该是什么?
编辑
好的,给你。下面是导出的 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"
}
}
}
我的目标只是显示消息(按顺序)以及用户名。如果我这样做:
ref.child("messages").on("child_added", function(snapshot) {
console.log(snapshot.val());
});
它按顺序显示消息,即消息 1、消息 2、消息 3。但是我仍然没有用户名,所以我需要在显示消息之前查看用户列表以检索用户名:
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);
});
});
那个 returns 包含用户名的消息列表,但问题是顺序错误:消息 2、消息 1、消息 3
邮件按您期望的顺序检索。您可以通过添加一些额外的日志记录轻松验证这一点:
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);
});
});
我最近运行的结果是:
"Message 1"
"Message 2"
"Message 3"
"Message 2: John Joe"
"Message 1: John Joe"
"Message 3: Alfred"
您在前三行中看到的是消息是有序的。但是您随后开始为每条消息检索用户;这些用户不一定会按照您 fired/expected 他们的顺序回来。
在 Web 上使用 AJAX 时,这是一个非常常见的问题:一旦涉及网络流量,代码的顺序就不一定是事情发生的顺序。
解决方案始终相同:不要依赖于您的代码以特定顺序执行。例如:您很可能希望在 DOM 某处的列表中显示消息。
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;
});
});
旁注:您可能需要考虑添加用户名缓存。您现在将为每个用户的每条消息调出数据库。这是一个 O(n^2) 操作,因此不能很好地扩展用户数量。