我有一个函数,在调用firebase数据库方面有一个函数。
内部函数从包装函数设置变量的值,但我的输出不会注册它。调试时看起来像是以相反的顺序发生。我是swift和firebase的新手,所以我只是试图让我的头围绕这个。
这是我的功能和输出。
func checkIfUsernameExists(inUsername: String) -> String{
var aString = "false"
let ref = FIRDatabase.database().reference()
ref.child("-KohvyrIikykRsOP0XCx").observeSingleEvent(of: .value , with: {(snapshot) in
if snapshot.hasChild(self.username.text!){
print ("*** username already exists")
aString = "true"
}
})
print ("*** value of aString is: ", aString)
return aString
}
输出是:
*** value of aString is: false
*** username already exists
编辑:
我认为我的问题很糟糕。
我想问的是如何在处理收集到的信息之前从firebase接收回叫。我已经反复出现了SO和许多博客都指向Async,GCD和Completion处理程序。其中任何一个似乎都不起作用或者很容易让诺布得到他们的头脑。
不用说我在这里找到了答案。
Firebase Swift 3 Completion handler Bool
这就是我用的:
func checkIfUsernameExists(userid: String, completionHandler: @escaping ((_ exist : Bool) -> Void)) {
let ref = FIRDatabase.database().reference()
ref.child("-KohvyrIikykRsOP0XCx").observeSingleEvent(of: .value , with: {(snapshot) in
if snapshot.hasChild(self.username.text!){
self.usernameCheck = "true"
completionHandler(true)
}
else {
self.usernameCheck = "false"
completionHandler(true)
}
})
}
答案 0 :(得分:0)
您似乎正在尝试从firebase数据库中获取值。你可能知道。 firebase数据库中的数据是远程存储的。这意味着与从磁盘获取数据相比,您需要相对较长的时间来处理数据。
由于花了这么长时间,firebase API的设计者认为“我们应该异步地获取数据,而不是让UI等待并变得无响应。这样,UI就不会冻结。”
在您的代码中,这段代码:
if snapshot.hasChild(self.username.text!){
print ("*** username already exists")
aString = "true"
}
将在获取数据后执行,这是一段时间之后。由于操作是异步完成的,因此函数的其余部分将继续执行,即此部分:
print ("*** value of aString is: ", aString)
return aString
在此阶段,闭包尚未完成执行,aString
为假。
这可能听起来很直观,但是考虑到这一点,你在这里调用方法 - observeSingleEvent
。闭包中的代码是一个参数。您只是告诉方法“在完成提取数据后运行此方法”。数据是异步提取的,因此之后的代码首先执行。