【问题标题】:Query an array in Firebase SWIFT在 Firebase SWIFT 中查询数组
【发布时间】:2016-05-13 15:14:54
【问题描述】:

使用 swift 和 firebase 我有一个这样的数据列表

{
"posts" : {
 "-KHbULJcKqt9bSpxNO9k" : {
  "author" : "Michele",
  "postText" : "tags as arrays?",
  "tag" : [ "HELLO", "WHAT'S UP?", "TEST" ]
}

还有更多帖子。我想按标签搜索,如果帖子包含搜索词作为标签,则返回整个帖子。我已经能够使用queryEqualToValue: 对字符串执行此操作,但无法为数组解决它。感谢您在正确方向上的任何一点。

这就是我的保存功能的样子

func createNewPost(post: Dictionary<String, AnyObject>, tags: [String]) {
    let firebaseNewPost = POST_REF.childByAutoId()
    let firebaseTag = Firebase(url: "\(POST_REF)/\(firebaseNewPost.key)/tag")

    print(firebaseTag)


    firebaseNewPost.setValue(post)

    for tag in tags {
        let tagID = firebaseTag.childByAutoId()

        tagID.setValue(tag)
    }
}

现在我需要帮助来搜索数据并根据用户搜索的内容检索特定帖子。这是我在它只是一个标签并且只是一个字符串时使用的。

    func loadTaggedShit(searchTerm: String) {

    DataService.dataService.POST_REF.queryOrderedByChild("tag").queryEqualToValue(seachTerm).observeEventType(.ChildAdded, withBlock: { snapshot in
        self.posts = []

        if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {
            for snap in snapshots {
                if let postDictionary = snap.value as? Dictionary<String, AnyObject> {
                    let key = snap.key
                    let post = Post(key: key, dictionary: postDictionary)

                    self.posts.insert(post, atIndex: 0)
                }
            }
        }

        self.tableView.reloadData()


    })

}

现在的数据也是这样的

"posts":{
 "-KHj_bDJmZJut7knKoUX" : {
  "author" : "Michele",
  "postText" : "what's up",
  "tag" : {
    "-KHj_bDJmZJut7knKoUY" : "HEY"
   }
 }
}

【问题讨论】:

    标签: arrays swift firebase firebase-realtime-database


    【解决方案1】:

    Firebase 数组非常适合情景,如果可能,确实应该避免使用。

    代码中的数组是非常强大的数据结构,但它们在 JSON 结构中不能很好地工作。如果它们被修改,例如删除一个节点,该索引也将被删除。这使阵列留下了“洞”,例如0, 1, 2, 4, 5, 7 等等。所以,在你的 post 节点中创建一个 tags 子节点,然后使用 childByAutoId 创建的键的子节点

    "posts" : {
     "-KHbULJcKqt9bSpxNO9k" : {
        "author" : "Michele",
        "postText" : "tags as arrays?",
        "tags"
           tag_id_0
             tag_title: "HELLO"
           tag_id_1
             tag_title: "WHAT'S UP?"
           tag_id_2
             tag_title: "TEST"
    }
    

    您甚至可以考虑创建一个单独的标签节点并在帖子节点中引用它 - 特别是如果它们可以重复使用。

    编辑:

    基于一些额外的信息,一个不同的结构将是有序的,因为 OP 需要查询包含特定标签的帖子,而这些标签实际上是可重用的,而不是特定于帖子的:

    posts
      -KHbULJcKqt9bSpxNO9k
        author: "Michele"
        postText: "tags as arrays?"
        tags
          tag_id_1: true
          tag_id_2: true
      -JPHJSojo91920LLK0J
        author: "Larry"
        postText: "NO, don't use arrays"
        tags
         tag_id_2: true
    
    tags
      tag_id_0
        tag_title: "HELLO"
      tag_id_1
        tag_title: "WHAT'S UP?"
      tag_id_2
        tag_title: "TEST"
    

    然后是接收所有使用 TEST 标签的帖子的代码,tag_id_2

    这称为 Firebase Deep Query

    postsRef.queryOrderedByChild("tags/tag_id_2").queryEqualToValue(true)
            .observeSingleEventOfType(.Value, withBlock: { snapshot in
        print(snapshot)
    })
    

    【讨论】:

    • 谢谢你,Jay,一旦用户发布了帖子就不会被修改,所以这会改变你的做法吗?
    • @Michi314 如果它们特定于帖子并且不会更改,则使用我发布的 Firebase 结构。这样它们就可以查询、可加载并且通常易于使用
    • 您将如何保存我尝试过的标签,但收到错误未指定 firebase 命名空间。这是我创建的函数 func createNewPost(post: Dictionary, tags: [String]) { let firebaseNewPost = POST_REF.childByAutoId() let firebaseTag = Firebase(url: "(firebaseNewPost.key)/tags" ) firebaseNewPost.setValue(post) for tag in tags { let tagID = firebaseTag.childByAutoId() tagID.setValue(tag) } }
    • @Michi314 最好不要在 cmets 中发布代码。如果有帮助,tag_is_0、tag_id_1 等是使用 childByAutoId 创建的节点。你能用你的后续问题更新你原来的问题吗?
    • 很抱歉,我刚刚弄明白了,但我会用我的新代码更新它,您能否帮助查询数据和查找特定帖子?谢谢
    猜你喜欢
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 2019-07-28
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多