【问题标题】:How to limit the child retrieved in Firebase Android如何限制在 Firebase Android 中检索到的孩子
【发布时间】:2017-06-05 04:40:36
【问题描述】:

我想问一下如何在 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 我必须使用带有 iterator 的 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 条消息吗?

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

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

    【讨论】:

    • 从您的回答中,这意味着我们必须知道chatroom_id 键和message_id 键?在我的情况下,密钥是随机生成的,所以我不知道聊天室和消息的密钥。在我们不知道 chatroom_id 和 message_id 的情况下,有什么办法可以做到吗?
    • 如果你不知道那个聊天室ID,你怎么知道从哪个房间取回消息?
    • 我正在使用迭代器从数据快照中检索我的 chatroom_id。问题是数据快照返回其中的所有子项。我想做的是将孩子限制为只有5个孩子。谢谢
    • 我对您可能需要的内容进行了猜测。但是,如果这仍然不能回答您的问题,请更新您的问题(使用下方的编辑链接)以包含 minimal code that reproduces where you are stuck。我们大多数人在这里试图提供帮助的人都比代码描述更擅长阅读代码。
    【解决方案2】:

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

    您需要“非规范化”您的数据。 与其将所有消息存储在聊天室中,不如将它们分开。

    诀窍是将所有消息单独存储为“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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 2017-06-20
      相关资源
      最近更新 更多