创建postDict之后如何从Firebase快照中检索和使用数据;我得到“ 0 \ 0 \ 0”

时间:2018-12-05 01:46:52

标签: ios swift firebase firebase-realtime-database

我看了几个问题和示例,但无济于事。我所采用的显示一系列帖子的方法“应该可行”,但由于某种原因,我无法访问快照数据中的键/值对...

在下面的代码中,我能够创建postDict并看到我需要的所有数据,但是我无法分配userID值,而不是通过的字符串值在调试控制台中看到以下内容: userID =(String)“ \ 0 \ 0 \ 0”

有什么想法吗?谢谢!

static func allPosts(completion: @escaping ([Post]) -> Void) {
    let postRef = Database.database().reference().child("posts")

    postRef.observeSingleEvent(of: .value, with: { (snapshot) in
        guard let snapshot = snapshot.children.allObjects as? [DataSnapshot]
            else { return completion([]) }

        let dispatchGroup = DispatchGroup()

        var posts = [Post]()

        for postSnap in snapshot {

            guard let postDict = postSnap.value as? [String : AnyObject],
                let userID = postDict["userID"] as? String

                else { continue }

            dispatchGroup.enter()

            PostFirebase.getPostByKey(postKey: postSnap.key, userID: userID, completion: { (post) in
                if let post = post {
                    posts.append(post)

                    print("posts array = \(posts)")
                }

                dispatchGroup.leave()
            })
        }

        dispatchGroup.notify(queue: .main, execute: {
            completion(posts.reversed())
        })
    })
}

这是/posts的JSON导出:

{
  "Tzgb6023LzYV8lVJr3KHbosdtR72" : {
    "-LQEw9M7DPZ0XugHdd7e" : {
      "noCount" : 0,
      "photoURL" : "https://firebasestorage.googleapis.com/...",
      "postText" : "soAwesome",
      "timestamp" : 5.62779748747864E8,
      "userID" : "Tzgb6023LzYV8lVJr3KHbosdtR72",
      "userPhotoURL" : "https://firebasestorage.googleapis.com/....",
      "username" : "ninjaone ",
      "videoURL" : "https://firebasestorage.googleapis.com/....",
      "voteCount" : 2,
      "yesCount" : 2
    }
  }
}

1 个答案:

答案 0 :(得分:0)

从JSON看来,/posts下有两个动态级别。我的猜测是,第一级是发布该帖子的用户的UID,而其下的级别是该帖子ID(通过调用childByAutoId生成)。

但是,您的代码仅循环到第一级(UID),然后尝试读取帖子。当然这是行不通的,因为下面还有另一个动态级别。因此,您将需要两个(嵌套的)循环:

let postRef = Database.database().reference().child("posts")

postRef.observeSingleEvent(of: .value, with: { (snapshot) in
    guard let snapshot = snapshot.children.allObjects as? [DataSnapshot]
        else { return completion([]) }

    let dispatchGroup = DispatchGroup()

    var posts = [Post]()

    for userSnap in snapshot {
      guard let postSnapshots = userSnap.children.allObjects as? [DataSnapshot]

      for postSnap in postSnapshots {

        guard let postDict = postSnap.value as? [String : AnyObject],
            let userID = postDict["userID"] as? String

            else { continue }

        dispatchGroup.enter()

        PostFirebase.getPostByKey(postKey: postSnap.key, userID: userID, completion: { (post) in
            if let post = post {
                posts.append(post)

                print("posts array = \(posts)")
            }

            dispatchGroup.leave()
        })
      }
    }

    dispatchGroup.notify(queue: .main, execute: {
        completion(posts.reversed())
    })
})