我需要多次观察,但我不知道如何。
这是我的数据库结构:
"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语句打印用户名,但第二个不打印任何内容。
提前致谢。
答案 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)
}