I'm using a UISearchController
and I want to query 2 nodes down from root on a comment key. It would be root > posts > uid > postId > comment
root
|
@--posts
|
@--uid123
|
@--postId987
|
|-comment: "I like pizza"
I tried chaining multiple queries let commentRef = postsRef.queryOrderedByKey().queryOrdered(byChild: "comment").queryStarting(atValue: searchText).queryEnding(atValue: searchText+"\u{f8ff}"
but I got a crash:
*** Terminating app due to uncaught exception 'InvalidQueryParameter', reason: 'Cannot use multiple queryOrderedBy calls!'
What's the best way to query several levels down?
Code that caused crash:
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text?.lowercased() else { return }
let postsRef = Database.database().reference().child("posts")
let commentRef = postsRef.queryOrderedByKey().queryOrdered(byChild: "comment").queryStarting(atValue: searchText).queryEnding(atValue: searchText+"\u{f8ff}")
commentRef.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionaries = snapshot.value as? [String: Any] else { return }
dictionaries.forEach({ (key, value) in
guard let dict = value as? [String: Any] else { return }
let post = Post(dict: dict)
let isContained = self.filteredComments.contains(where: { (containedPost) -> Bool in
return post.comment == containedPost.comment
})
if !isContained {
self.filteredComments.append(post)
self.collectionView?.reloadData()
}
})
})
}
I found another way to do it below. I first get the .value
on the posts ref, loop through all the children, then I attach each snapshot.key
as a child to the postsRef and get the comment from there. It actually works. The problem is it doesn't seem very efficient especially if there are millions of posts and/or users to sort through.
let postsRef = Database.database().reference().child("posts")
postsRef.observeSingleEvent(of: .value) { (snapshot) in
for child in snapshot.children {
let uid = child as! DataSnapshot
let commentRef = postsRef.child(uid.key).queryOrdered(byChild: "comment").queryStarting(atValue: searchText).queryEnding(atValue: searchText+"\u{f8ff}")
commentRef.observeSingleEvent(of: .value, with: { (snapshot) in
// the rest of the code
}