iOS Firebase-向下查询多个级别的最佳方法是什么? “ InvalidQueryParameter”,原因:“无法使用多个queryOrderedBy调用!”

时间:2018-08-01 21:12:16

标签: ios swift firebase firebase-realtime-database

我正在使用UISearchController,我想在注释键上从根向下查询2个节点。应该是root > posts > uid > postId > comment

root
  |
  @--posts
       |
       @--uid123
            |
            @--postId987
                  |
                  |-comment: "I like pizza"

我尝试链接多个查询let commentRef = postsRef.queryOrderedByKey().queryOrdered(byChild: "comment").queryStarting(atValue: searchText).queryEnding(atValue: searchText+"\u{f8ff}",但发生崩溃:

  

***由于未捕获的异常'InvalidQueryParameter'而终止应用程序,原因:'无法使用多个queryOrderedBy调用!'

什么是向下查询多个级别的最佳方法?

导致崩溃的代码:

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()
            }
        })
    })
}

我在下面找到了另一种方法。我首先在posts ref上获得.value,循环遍历所有子项,然后将每个snapshot.key作为子项附加到postsRef并从那里获取评论。它确实有效。问题在于,它似乎效率不高,尤其是当有数百万的帖子和/或用户需要整理时。

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
    }

2 个答案:

答案 0 :(得分:0)

根据this answer,当您到达要查询的最终节点时,Firebase只能查询一级深度,不支持使用动态节点(由childByAutoId创建的节点)在多个深度路径中进行查询

示例您无法查询root > posts > postId > userId > whatever your looking for,因为postId和userId都是动态的。

似乎达到我要求的唯一方法是复制数据并在该复制路径中进行搜索。

root > posts > postId > whatever your looking for

enter image description here

答案 1 :(得分:0)

我将把它作为可能的解决方案。

尚不清楚当前结构为何如此,但我建议将其更改为

post_comments
   post_id_x
      posted_by: "uid1234"
      comment: "I like pizza"

如果结构需要保持原样,则只需将其添加为另一个节点,这将使您的注释查询更加简单。