0

enter image description here

I have this type of structure in my firebase real time db. I want to fetch multiple child's last item's data for only once.

I am following below approach :

for (roomId in roomInformation.keys) { 

// roomInformation will contain some of room ids 
// to fetch from firebase db(not all roomIds from Messages)
    
    val messageObserver = object : ValueEventListener {
    ...
    }
    
    FirebaseDatabase.getInstance().reference
                .child("Messages")
                .child(roomId)
                .limitToLast(1)
                .addListenerForSingleValueEvent(messageObserver)
    
}

I don't want to fetch all childs (roomIds) from Messages Collection. This looping approach to get data from firebase is working but I want to fetch required records in a single callback (without for loop). Is there any possibility to do this or Is there any other better approach for same?

UPDATE: More clarification:

As per image: there is one Messages collection which include id's of Rooms and inside that rooms there are thousands of messages. I want to fetch all room's last message. So as per query I applied: Messages -> RoomId -> limitToLast(1) so It will give me last message info of particular room. User might join with hundreds of rooms and initially when user do login I want to display all rooms last message. so I am fetching messages of rooms by using for loop so Firebase will give me a single room last message at a time but I want all rooms last messages at a time. Here all room in the sense, Messages Collection is having 300 Rooms and If UserA is joined with 50 rooms then I only wants last messages of 50 rooms

Nik
  • 1,991
  • 2
  • 13
  • 30
  • Can you make it more clear by adding for database screenshots and also the reason for not wanting to make use of loop . Also some more information about the logic that you are using can be helpful . – Karunesh Palekar Aug 20 '21 at 08:35
  • Hey Nik. To understand better. Do you want to get all objects that exist within the Messages node? Meaning two-level deep in the node? – Alex Mamo Aug 20 '21 at 09:01
  • @KARUNESHPALEKAR - added more clarification. Reason not to make for loop -> To minimize Firebase call and reduce time to fetch data – Nik Aug 20 '21 at 09:59

1 Answers1

1

Firebase queries function on a flat list of nodes, so they can't query across all rooms that you have under /Messages in one go. But firing multiple queries is not as slow as many developers think, as Firebase pipelines the requests over a single web socket connection.

If you don't want to make multiple calls, the solution is to add an additional data structure that has exactly what you need. For example, it is quite common for a chat app on Firebase to have a top-level node:

"latestMessagePerRoom": {
  "theSameRoomIdYouAlreadyHave": {
    "timestamp": 1604488509642,
    "message": ...
    ...
  }
}

So whenever you push() a message to a chat room, you also set it to this location. You'll end up with some duplicate data, but now your use-case of showing the latest message for all rooms becomes trivial to implement.

This is a common trade-off when working with NoSQL databases, and my common recommendation is to make your data model closely reflect what you're showing on your screen. So here: if you're showing a list with the latest message for each chat room, that's also what we're storing in the database.

For some more guidance on such data modeling consideration, I recommend checking out NoSQL data modeling and David East's excellent Firebase for SQL developers video series.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807