我希望我的方法等到Firebase请求完成
在Firebase请求完成之前 uploadSingUpInfo
返回,这对我来说是个问题 - 某些方法返回nil。
static func uploadSingUpInfo(fullName:String,email:String,password:String)->String{
rootRef = FIRDatabase.database().reference()
var returnVlue="not valid"
FIRAuth.auth()?.createUserWithEmail(email, password: password) { (user, error) in
if (error != nil){
returnVlue=(error?.userInfo["error_name"]) as! String
}
else{
let newUser = [
"username": fullName
]
rootRef.childByAppendingPath("User")
.childByAppendingPath((user?.uid)!).setValue(newUser)
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isLogin")
NSUserDefaults.standardUserDefaults().setObject(email, forKey: "email")
NSUserDefaults.standardUserDefaults().setObject(user?.uid, forKey: "user_ID")
print(NSUserDefaults.standardUserDefaults().objectForKey("user_ID"))
returnVlue="valid"
}
}
return returnVlue
}
答案 0 :(得分:5)
不要将Firebase用作返回值的函数 - 它违背了它的异步性质。
规划代码结构,允许Firebase执行它的任务,然后在闭包(块)内转到下一步。
例如:在您的代码中,将函数更改为不返回任何内容并在createUserBlock中,作为最后一行而不是return,调用下一个函数来更新UI。
static func uploadSingUpInfo(fullName:String,email:String,password:String) {
rootRef = FIRDatabase.database().reference()
FIRAuth.auth()?.createUserWithEmail(email, password: password) { (user, error) in
if (error != nil){
showUserAnError(error)
} else {
let newUser = [
"username": fullName
]
rootRef.childByAppendingPath("User")
.childByAppendingPath((user?.uid)!).setValue(newUser)
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isLogin")
NSUserDefaults.standardUserDefaults().setObject(email, forKey: "email")
NSUserDefaults.standardUserDefaults().setObject(user?.uid, forKey: "user_ID")
print(NSUserDefaults.standardUserDefaults().objectForKey("user_ID"))
continueLoginProcess() //reload the ui or whatever step is next
}
}
}
答案 1 :(得分:3)
在您的代码中,该方法在firebase请求完成之前返回,因此不会设置returnVlue
的值。
正常功能不等待异步功能完成运行; - 因为那是异步功能的重点。不是吗?
因此,如果您希望uploadSingUpInfo
等到createUserWithEmail
完成,那么您必须使用 completionHandlers 使createUserWithEmail
成为异步函数:
func uploadSingUpInfo(fullName: String, email: String, password: String, completion: (result: String) -> Void) {
FIRAuth.auth()?.createUserWithEmail(email, password: password) {
(user, error) in
if (error != nil){
returnVlue=(error?.userInfo["error_name"]) as! String
}
else{
let newUser = [
"username": fullName
]
rootRef.childByAppendingPath("User")
.childByAppendingPath((user?.uid)!).setValue(newUser)
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isLogin")
NSUserDefaults.standardUserDefaults().setObject(email, forKey: "email")
NSUserDefaults.standardUserDefaults().setObject(user?.uid, forKey: "user_ID")
print(NSUserDefaults.standardUserDefaults().objectForKey("user_ID"))
returnVlue="valid"
}
completion(returnVlue);
}
}
这就是你怎么称呼这个方法:
uploadSingUpInfo(<arguments>) {
(result: String) in //this is what you pass to completion handler.
print("got back: \(result)")
}
有关更好的建议,请参阅this article。
答案 2 :(得分:1)
而不是从该函数返回值。您可以在&#34;非常结束时调用firebase方法中的另一个函数&#34;方法。这将确保您在接下来需要执行的任何功能时,在Firebase完成处理您的请求时结束时执行
FIRAuth.auth()?.createUserWithEmail(email, password: password) { (user, error) in
if (error != nil){
returnVlue=(error?.userInfo["error_name"]) as! String
}
else{
let newUser = [
"username": fullName
]
rootRef.childByAppendingPath("User")
.childByAppendingPath((user?.uid)!).setValue(newUser)
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isLogin")
NSUserDefaults.standardUserDefaults().setObject(email, forKey: "email")
NSUserDefaults.standardUserDefaults().setObject(user?.uid, forKey: "user_ID")
print(NSUserDefaults.standardUserDefaults().objectForKey("user_ID"))
returnVlue="valid"
}
callAnotherFunctionWhenFinished()
}