如何使用Firebase进行多次观察?

时间:2016-12-15 09:15:58

标签: ios swift firebase firebase-realtime-database

我需要多次观察,但我不知道如何。

这是我的数据库结构:

"Posts" : {
"f934f8j3f8" : {
  "data" : "",
  "date" : "",
  "userid" : "" 
}
},  
"Users" : {
"BusWttqaf9bWP224EQ6lOEJezLO2" : {
  "Country" : "",
  "DOB" : "",
  "Posts" : {
    "f934f8j3f8" : true
  },
  "Profilepic" : "",
  "name" : "",
  "phonenumber" : ""
}

我想观察这些帖子并编写代码并且效果很好,但我也希望得到发布此帖子的用户的名字,但是当我写下保存名称并使用它时它会给我null。这是我的代码。

DataServices.ds.REF_POSTS.queryOrderedByKey().observe(.value, 
                       with: { (snapshot) in

     self.posts = []

     if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {

         for snap in snapshot {

             if let postsDict = snap.value as? Dictionary<String, AnyObject> {

                let key = snap.key

                let userID = "BusWttqaf9bWP224EQ6lOEJezLO2"
                DataServices.ds.REF_USERS.child(userID).observeSingleEvent(of: .value, with: { (snapshot) in
                    let value = snapshot.value as? NSDictionary
                    let postusername = value?["name"] as? String ?? ""
                })
                print(" ------ User name : \(postusername) ------")
              })

              print(" ------ User name 2 : \(postusername) ------")

              let post = Posts(postKey: key, postData: postsDict)
              self.posts.append(post)

第一个print语句打印用户名,但第二个不打印任何内容。

提前致谢。

1 个答案:

答案 0 :(得分:1)

Firebase是异步的,因此在Firebase在其关闭内填充变量之前,您无法对变量进行操作。此外,代码比互联网更快,因此关闭后的任何语句都将在之前发生闭包内的语句。

流程如下

Query for the post {
  get the user id from the post inside this closure
  query for the user info {
     create the post inside this second closure
     append the data to the array inside this second closure
     reload tableview etc inside this second closure
  }
}

像这个编辑过的代码

self.posts = []
myPostsRef.queryOrderedByKey().observe(.value, with: { (snapshot) in


 if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
   for snap in snapshot {
        if let postsDict = snap.value as? Dictionary<String, AnyObject> {

            let key = snap.key

            let userID = "BusWttqaf9bWP224EQ6lOEJezLO2"
            myUsersRef.child(userID).observeSingleEvent(of: .value, with: { (snapshot) in
                let value = snapshot.value as? NSDictionary
                let userName = value?["name"] as? String ?? ""
                let post = Posts(postKey: key, postData: postsDict, name:userName)
                self.posts.append(post)
            })
         }
    }
  }
})

您没有在闭包内使用postusername,所以我将其添加到Posts初始化。

此外,self.posts = []将在posts节点发生更改时重置posts数组 - 您可能需要先考虑加载数组,然后观察添加,更改或删除只需用一次更改来更新posts数组,而不是每次都重新加载整个数组。

编辑:

对循环外无法获得的数据发表评论。这是一个非常简化和经过测试的版本。单击按钮1,使用一系列字符串从Firebase填充数组,单击按钮2打印数组。

var posts = [String]()

func doButton1Action() {

    let postsRef = ref.child("posts")
    self.posts = []
    postsRef.observe(.value, with: { (snapshot) in

        if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
            for snap in snapshot {
                let value = snap.value as! String
                self.posts.append(value)
            }
        }
    })

}

func doButton2Action() {
    print(posts)
}