2017-06-05 53 views
0

我想了解如何在Android Firebase中使用有限子女检索数据。这里是我的数据结构:如何限制在Firebase中检索到的孩子Android

"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

要检索子节点的子集,请使用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个聊天室。

+0

从你的回答就意味着我们必须知道chatroom_id键和MESSAGE_ID关键?在我的情况下,密钥是随机生成的,所以我不知道聊天室和消息的关键。如果我们不知道chatroom_id和message_id,有没有办法做到这一点? – VincentTheonardo

+0

如果你不知道聊天室ID,你怎么知道从哪个房间检索消息? –

+0

我正在使用迭代器从datasnapshot中检索我的chatroom_id。问题是datasnapshot返回里面的所有子项。我想要做的就是限制孩子回到只有5个孩子。谢谢 – VincentTheonardo

0

尽管可以做,但您当前的数据库结构对于这类查询并不理想。

您需要“非规范化”您的数据。 而不是存储聊天室内的所有消息将它们分开。

诀窍是将所有消息分别存储为“chatroom_id”下的列表。这样,您可以轻松获取给定聊天室的所有消息,并使用Firebase限制API。

喜欢的东西

/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) 

这将减少带宽使用的额外的好处,当你只是需要从那以后聊天室列表整个消息列表将不会被提取。

Firebase Reference

相关问题