【发布时间】:2017-02-15 23:12:07
【问题描述】:
我正在尝试实现一个完成处理程序来处理我调用 firebase 返回的结果。到目前为止,当我调用该函数时,它会直接跳转到completionHandler(result!) 并返回 nil。我做错了什么?
//View Controller
FireChangePassword(email: (User.current?.email)!, currentPassword: currentPassword!, newPassword: newPassword!, completionHandler: { (result) -> Void in
if result == ChangePasswordResult.AuthError{
errorLabel.text = "Incorrect Passworld"
}
else if result == ChangePasswordResult.FBError{
errorLabel.text = "System Error"
}
else if result == ChangePasswordResult.Success{
_ = self.navigationController?.popToRootViewController(animated: true)
}
})
//Firebase.swift
enum FirebaseErrors:Error {
case AuthError
case FBError
case Success
}
typealias CompletionHandler = (_ result:ChangePasswordResult) -> Void
func FireChangePassword(email: String, currentPassword: String, newPassword: String, completionHandler: CompletionHandler) {
let user = FIRAuth.auth()?.currentUser
let credential = FIREmailPasswordAuthProvider.credential(withEmail: email, password: currentPassword)
var result : ChangePasswordResult?
user?.reauthenticate(with: credential) { error in
if let error = error {
// An error happened.
print("Firebase ReAuthentication Error")
print(error)
result = ChangePasswordResult.AuthError
} else {
// User re-authenticated.
FIRAuth.auth()?.currentUser?.updatePassword(newPassword) { (error) in
if error == nil {
print("Firebase Change Password Successful")
result = ChangePasswordResult.Success
}
else {
print(error!)
print("Firebase Change Password Failed")
result = ChangePasswordResult.FBError
}
}
}
}
completionHandler(result!)
}
【问题讨论】:
-
你为什么要这样做?处理闭包内的错误(这是它的设计方式)。如果有错误返回之前的 viewController 并通知用户,如果没有错误,则继续。试图通过 throws 处理它会导致各种异步问题..
-
我不确定我知道该怎么做。我正在尝试从
FireChangePassword返回一些东西,所以我知道是否有错误或请求是否成功。但是对 firebase 的调用是异步的,并且函数会在 firebase 返回结果之前继续前进,所以我的FireChangePassword最终返回了一个 nil 值。 -
没错。 Firebase 是异步的,并非旨在返回值 - 返回实际上是用于同步方法。当 Firebase 数据有效时,它将在 Firebase 函数调用之后的闭包内。从那里您可以确定密码是否已成功更改。如果不是,只需返回 viewController 并通知用户,如果是,则继续前进到下一个控制器。在封闭件内完成所有这些操作,其余的将就位。
-
对不起,我仍然没有看到如何实施您的解决方案。我的问题是我创建了一个单独的 swift 文件来处理我所有的 firebase 调用。我无法从 firebase 闭包中弹出视图控制器,因为它没有在视图控制器中定义。所以我认为我必须自定义 firebase 调用以使用完成处理程序来让我知道是否有错误或请求是否成功。
-
你会想要改变你的策略,因为 Firebase 中的一切都是异步的,并且期望返回值会有问题。将 Firebase 调用作为应用流程的一部分实现...用户输入新密码并点击更改,调用 Firebase 函数来更改密码。如果成功则在内部关闭,然后移动到下一个 viewController。如果不在同一个 viewController 上并显示错误消息。尝试实现完成处理程序将导致相同的问题,因为在调用结果发生关闭之前,您绝对不能在 UI 中继续前进。
标签: ios firebase swift3 firebase-authentication