Lance Samaria
Lance Samaria

Reputation: 19622

Swift -Firebase get last childKey from a subset of snapshot.children

How can I get the last child key from a subset of child keys? For eg. in the loop I want to grab Lqouwhrbcausobc8abc and Lkasjhvbafoshvb8xyz in the getLastChildKey() function

db:

messageIds-userIds
    |
    @--currentUserId
           |
           @--XcAUw75y6vXBxCiNl3flrl9qcztob 
           |      |-Laouhfbobhvahsblask : 1
           |      |-Lwbiuwripibpiwbjvcp : 1
           |      |-Lqouwhrbcausobc8abc : 1  // I want to grab this messageId
           |
           @--ZBBglasjdbvj2X8zbMwasdbpBzOOp21w
                  |-Laofbhaphvbapsjvbpa : 1
                  |-Lljafhbvpojhfbvaljk : 1
                  |-Lkasjhvbafoshvb8xyz : 1  // I want to grab this messageId

code:

let ref = Database.database().reference().child(messageIds-userIds)

ref.child(currentUserId)
   .queryOrderedByKey()
   .queryLimited(toLast: 20)
   .observe( .value, with: { (snapshot) in

       for child in snapshot.children.allObjects as! [DataSnapshot] {

           let userId = child.key

           self.getLastChildKey(from: userId, childSnapshot: child)
       }
})

func getLastChildKey(from userId: String, childSnapshot: DataSnapshot) {

    for child in childSnapshot.children {
            
        let snap = child as! DataSnapshot
            
    }
}

Upvotes: 2

Views: 175

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 600036

There is no way to get just the last child node from each child node with a single read operation. While it is possible to get the last child node of a node, you will have to know the complete path of the parent node in that case.

This boils down to the fact that Firebase Realtime Database queries operate on a list of child nodes, and not on a tree.

  • So you can request only the last (or first) child of messageIds-userIds, since you know the full path to that messageIds-userIds node.

  • If you know the currentUserId then you can request the first/last child of that node too.

  • And if you were to know both the currentUserId and XcAUw75y6vXBxCiNl3flrl9qcztob, then you could request the first/last child of that node too.

But if you only know the messageIds-userIds and want to get the last child of each of its currentUserId/$XcAUw75y6vXBxCiNl3flrl9qcztob child nodes, you will need to read the entire structure as you're doing now.


It often helps to model the data for the use-cases of your app. In this case, consider storing the last child node for each path in a single list.

lastChildNodes: {
    "currentUserId XcAUw75y6vXBxCiNl3flrl9qcztob": "-Lqouwhrbcausobc8abc"
    "currentUserId ZBBglasjdbvj2X8zbMwasdbpBzOOp21w": "-Lkasjhvbafoshvb8xyz"
}

Code sample:

func getLastChildKey(from userId: String, childSnapshot: DataSnapshot) {
    DataSnapshot last = nil
    for child in childSnapshot.children {            
        snap = child as! DataSnapshot            
    }
    return snap
}

Upvotes: 2

Related Questions