我想询问如何在Android Firebase中使用受限子项检索数据。这是我的数据结构:
"chatrooms":
"chatroom_id_1" :
"message":
"message_id_1":1
"message_id_2":1
"message_id_3":1
"message_id_4":1
"message_id_5":1
"message_id_6":1
"message_id_7":1
"message_id_8":1
"message_id_9":1
"message_id_10":1
"message_id_11":1
"chatroom_id_2" :
"message":
"message_id_12":1
"message_id_13":1
"message_id_14":1
"message_id_15":1
"message_id_16":1
"message_id_17":1
"message_id_18":1
"message_id_19":1
"message_id_20":1
"message_id_21":1
"message_id_22":1
从上面的结构如何进行查询以检索仅包含5条消息的数据的快照?
我想拥有的dataSnapshot是这样的:
DataSnapshot {
key = chatroom_id_1,
value = {
messages={
message_id_1=1,
message_id_2=1,
message_id_3=1,
message_id_4=1,
message_id_5=1
}
}
}
DataSnapshot {
key = chatroom_id_2,
value = {
messages={
message_id_12=1,
message_id_13=1,
message_id_14=1,
message_id_15=1,
message_id_16=1
}
}
}
可以这样做吗?因为我发现的大部分教程只能限制被检索的孩子而不是内心的孩子。感谢
编辑:我的message_id是随机生成的,所以为了获得message_id,我必须使用带迭代器的DataSnapshot。这是我的检索数据代码
public void retrieveChatRoom(final Callback callback){
DatabaseReference ref = reference.child("chatrooms");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
callback.onDataChanged();
Iterator i = dataSnapshot.getChildren().iterator();
while (i.hasNext()) {
DataSnapshot dataSnapshot1 = (DataSnapshot) i.next();
callback.dataReceived(dataSnapshot1);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
问题是DataSnapshot返回我聊天室内的所有chat_message,我可以将其限制为仅返回5条消息吗?
答案 0 :(得分:0)
要检索子节点的子集,请使用Firebase queries。如果要将子节点同步到某个键,则使用:
Query query = ref.child("chatroom_id_1/message")
.orderByKey()
.endAt("message_id_5");
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
System.out.println(childSnapshot.getKey());
}
}
...
如果您只想从某个位置获取5条消息:
Query query = ref.child("chatroom_id_1/message")
.orderByKey()
.limitToFist(5);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
System.out.println(childSnapshot.getKey());
}
}
...
<强>更新强>:
Firebase数据库查询可以根据您执行它们的位置的每个子节点的固定属性(或路径)来限制结果。无法一次性检索每个聊天室的最后5条消息。您可以检索特定聊天室的最后5条消息。或者最后5个聊天室。
答案 1 :(得分:0)
尽管可以这样做,但您当前的数据库结构并不适合这些类型的查询。
您需要“反规范化”您的数据。 而不是将所有消息存储在聊天室中,而不是将它们分开。
诀窍是将所有邮件分别存储为“chatroom_id”下的列表。这样,您可以轻松获取给定聊天室的所有消息,并使用firebase limit apis。
像
这样的东西/chatrooms
- chatroom_id1
{
name,
last_message,
timestamp
}
/messages
- chatroom_id //<-- Notice this
{
sender,
content,
timestamp
} //<-- Add new child messages here
然后,您可以获取给定chatroom_id的消息,例如
//Get chatroom list and details
ref.child("chatrooms")
ref.child("chatrooms").child("some_chatroom_id")
//Get limited messages
ref.child("messages").child("some_chatroom_id").limitToFirst(10)
当您只需要一个聊天室列表时,这将有额外的好处,即减少带宽使用,从那时起,将不会获取整个消息列表。