【问题标题】:Firebase snapshot not being cast to dictionaryFirebase 快照未转换为字典
【发布时间】:2017-08-18 22:26:36
【问题描述】:

我有这个函数应该从 firebase 的 comments node 获取数据。我想实现 pagination 一次不加载 100 多个 cmets。一切似乎都正常,但我的代码似乎无法将 snapchat.value 转换为 Dictionary

     func fetchComments(){
        messagesRef = Database.database().reference().child("Comments").child(eventKey)
        var query = messagesRef?.queryOrderedByKey()
        if comments.count > 0 {
           let value =  comments.last?.commentID
            query = query?.queryStarting(atValue: value)
        }
        query?.queryLimited(toFirst: 2).observe(.childAdded, with: { (snapshot) in

            var allObjects = snapshot.children.allObjects as? [DataSnapshot]

            allObjects?.forEach({ (snapshot) in
                 // print out snapshot and it isn't empty 
                print(snapshot.value) // here it keeps going into the else statement even though snapshot.value clearly exist.

                guard let commentDictionary = snapshot.value as? [String:Any] else{
                    return
                }

                print(commentDictionary)
            })
                   }) { (err) in
            print("Failed to observe comments")
        }
    }

我的问题是任何人都可以看看这个,也许看看我哪里出错了?我的代码对我来说看起来不错,但我看不出有什么问题。

我的树是这样的

"Comments" : {
"CCDS" : {
  "-KrrsXkj6FznzRD0-Xzs" : {
    "content" : "Shawn",
    "profileImageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/profile_images%2FBC868F8F-E9EC-4B9D-A248-DD2187BC140C.PNG?alt=media&token=fb14700c-2b05-4077-b45c-afd3de705801",
    "timestamp" : 1.503102381340935E9,
    "uid" : "oxgjbrhingbf7vbaHpflhw6G7tB2"
  }
},
"MIA" : {
  "-Krghz9d5_CPjkmdffef" : {
    "content" : "22",
    "profileImageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/profile_images%2FF50F6915-DEAB-4A5B-B1AB-CABC1E349148.PNG?alt=media&token=4eb7c708-ec87-45bf-952d-0bd410faee50",
    "timestamp" : 1.502915064803007E9,
    "uid" : "oxgjbrhingbf7vbaHpflhw6G7tB2"
  },
  "-KrpoEnNYsmRZ5guORUj" : {
    "content" : "23",
    "profileImageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/profile_images%2FBC868F8F-E9EC-4B9D-A248-DD2187BC140C.PNG?alt=media&token=fb14700c-2b05-4077-b45c-afd3de705801",
    "timestamp" : 1.503067700479352E9,
    "uid" : "oxgjbrhingbf7vbaHpflhw6G7tB2"
  }
}
  }

根据我的代码,它绕过密钥并直接传给孩子们。 例如,如果传入 MIA,它应该转到 MIA 并获取与每个评论“-KrrsXkj6FznzRD0-Xzs”和“-KrpoEnNYsmRZ5guORUj”相对应的密钥,但它会返回该唯一 ID 下的所有内容。这是个问题

【问题讨论】:

  • 我认为您的问题是您重复使用了 snapshot 变量,我会将 allObjects?.forEach({ (snapshot) 中的名称更改为类似 `eachObj.所以你可能不知道你打印的是哪一个
  • 好的,我会试试的
  • 似乎有效,但这很奇怪,我不明白这会如何影响它
  • 它正在工作或似乎正在工作?
  • 好吧,它没有命中 return 语句,所以我猜它正在被分配。

标签: swift dictionary firebase firebase-realtime-database


【解决方案1】:

您的回调中的代码似乎假定您是使用一组 cmets 调用的。要获得这样的集合,您需要观察.value 事件。当您观察到.value 事件时,您的回调会被一个包含与查询匹配的所有节点的snapshot 调用:

   query?.queryLimited(toFirst: 2).observe(.value, with: { (snapshot) in

        var allObjects = snapshot.children.allObjects as? [DataSnapshot]

        allObjects?.forEach({ (snapshot) in
            print(snapshot.key)
            print(snapshot.value)

            guard let commentDictionary = snapshot.value as? [String:Any] else{
                return
            }

            print(commentDictionary)
        })
    }) { (err) in
        print("Failed to observe comments")
    }

当您观察到.childAdded 时,您的回调会为每个匹配查询的单个节点调用。这意味着您需要摆脱代码中的循环:

   query?.queryLimited(toFirst: 2).observe(.childAdded, with: { (snapshot) in
        print(snapshot.key)
        print(snapshot.value)

        guard let commentDictionary = snapshot.value as? [String:Any] else{
            return
        }

        print(commentDictionary)

    }) { (err) in
        print("Failed to observe comments")
    }

【讨论】:

  • 其中哪一项将允许实时更新 cmets?
  • 一个侧面的问题。您知道当您在 Instagram 上搜索某些内容时,用户找到的结果似乎是实时弹出的。有没有办法做到这一点而不将所有结果从firebase添加到数组并查询
  • 我需要你的帮助
猜你喜欢
  • 1970-01-01
  • 2016-10-28
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多