【问题标题】:How to make app wait until Firebase request is finished如何让应用程序等到 Firebase 请求完成
【发布时间】:2017-01-04 13:44:22
【问题描述】:

我希望我的方法等到 Firebase 请求完成

uploadSingUpInfo 在 Firebase 请求完成之前返回,这对我来说是个问题 - 某些方法返回 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

}

【问题讨论】:

  • 不要使用 Firebase 作为返回值的函数——这违背了它的异步特性。您应该计划您的代码以允许 Firebase 执行它的任务,然后在闭包(块)内转到下一步。例如,在您的代码中删除返回并在 createUserBlock 中,作为最后一行而不是返回,调用您的下一个函数来更新您的 UI。

标签: ios swift firebase firebase-realtime-database firebase-authentication


【解决方案1】:

不要将 Firebase 用作返回值的函数 - 这违背了它的异步特性。

规划允许 Firebase 执行其任务的代码结构,然后在闭包(块)内进行下一步。

例如:在您的代码中,将函数更改为不返回任何内容,并在 createUserBlock 中,作为最后一行而不是返回,调用下一个函数来更新您的 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
        }
      }
    }

【讨论】:

  • @Sammer 你能说得更具体点吗? “表”是什么意思?
【解决方案2】:

在您的代码中,该方法在 firebase 请求完成之前返回,因此不会设置 returnVlue 的值。

普通函数不会等待异步函数完成运行;- 因为这就是异步函数的意义所在。不是吗?

因此,如果您希望 uploadSingUpInfo 等到 createUserWithEmail 完成,那么您还必须使用 completionHandlerscreateUserWithEmail 设为异步函数:

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 以获得更好的想法。

【讨论】:

  • 你是说字典吗?那么,您必须确保仅在生成返回值所需的所有代码都已执行后才调用完成。
【解决方案3】:

而不是从该函数返回值。您可以在方法的“最后”调用 firebase 方法内的另一个函数。这将确保在 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()
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多