私は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に戻り、エラーがなければユーザーに通知し、続行します。スローを通してそれを処理しようとすると、あらゆる種類の非同期の問題が発生します。 – Jay
私はそれをどうやって行うのか分かりません。 'FireChangePassword'から何かを返そうとしているので、エラーがあったか、リクエストが成功したかどうかを知っています。しかし、firebaseの呼び出しは非同期であり、firebaseが結果を返す前に関数が先に進むので、私の 'FireChangePassword'は無限の値を返すようになります。 – Brosef
それは正しいです。 Firebaseは非同期であり、値を返すようには設計されていません - 返品は実際には同期メソッド用です。 Firebaseデータが有効な場合、Firebase関数呼び出しに続いてクロージャ内にあります。そこから、パスワードが正常に変更されたかどうかを判断できます。そうでない場合は、単にviewControllerに戻ってユーザーに通知し、そうであれば次のコントローラに移動します。閉鎖の内側にあるすべてと残りの部分が落ちますか? – Jay