通过单个功能更新Firebase电子邮件和用户名,并迅速进行错误处理

时间:2019-03-09 13:26:01

标签: swift firebase firebase-authentication

我有一个按钮,当前用户可以在其中更新其电子邮件和用户名。

我当前的功能是

<context-param>
    <param-name>org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES</param-name>
    <param-value>3628800000</param-value> <!-- 6 weeks. -->
</context-param>

然后我在按下按钮时调用此函数

 func updateDetails(withEmail email: String, andDisplayName 
 displayName: String, updateComplete: @escaping(_ error: Error?) -> ()) {

        let currentUser = Auth.auth().currentUser
        currentUser?.updateEmail(to: email, completion: { (error) in
            if let error = error {
                self.createError(title: "Error updating email", message: "\(error.localizedDescription)")
            } else {
                let ref = Database.database().reference().child("Users").child((self.user?.uid)!).child("email")
                ref.setValue(Auth.auth().currentUser?.email)
        }
    })

        let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
        changeRequest?.displayName = displayName
        changeRequest?.commitChanges { (error) in
            if error != nil {
                self.createError(title: "Error updating display name", message: "\(String(describing: error?.localizedDescription))")
            } else {
                let ref = Database.database().reference().child("Users").child((self.user?.uid)!).child("name")
                ref.setValue(Auth.auth().currentUser?.displayName)
                self.welcomeLabel.text = "Hi, \(self.currentUserNameTextField.text ?? "")"
            }
        }

}

详细信息将在身份验证和数据库中更新,但是这段代码从未运行过

@IBAction func saveChangesButtonPressed(_ sender: Any) {

    if emailTextField.text == nil || currentUserNameTextField.text == nil {
        createError(title: "Error", message: "Email and name fields must not be blank")
    } else {
        updateDetails(withEmail: emailTextField.text!, andDisplayName: currentUserNameTextField.text!) { (error) in
            if error == nil {
                self.createError(title: "Success", message: "")
            } else {
                self.createError(title: "Error", message: "\(error!.localizedDescription)")
            }
        }
    }
}

有人会知道为什么没有调用它吗?

谢谢

1 个答案:

答案 0 :(得分:0)

在调用updateDetails(withEmail email: String, andDisplayName displayName: String, updateComplete:)的过程中传递了完成处理程序时,该函数的实现从不调用updateComplete:。这不会自动发生,但是您必须自己实现。

由于您有两个操作,因此我假设您只想在两个操作都完成后才调用完成处理程序。一种简单的实现方法是依次执行两个操作:

func updateDetails(withEmail email: String, andDisplayName 
 displayName: String, updateComplete: @escaping(_ error: Error?) -> ()) {
    let currentUser = Auth.auth().currentUser
    currentUser?.updateEmail(to: email, completion: { (error) in
        if let error = error {
            self.createError(title: "Error updating email", message: "\(error.localizedDescription)")
            completion(error)
        } else {
            let ref = Database.database().reference().child("Users").child((self.user?.uid)!).child("email")
            ref.setValue(Auth.auth().currentUser?.email)


            let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
            changeRequest?.displayName = displayName
            changeRequest?.commitChanges { (error) in
                if error != nil {
                    self.createError(title: "Error updating display name", message: "\(String(describing: error?.localizedDescription))")
                } else {
                    let ref = Database.database().reference().child("Users").child((self.user?.uid)!).child("name")
                    ref.setValue(Auth.auth().currentUser?.displayName)
                    self.welcomeLabel.text = "Hi, \(self.currentUserNameTextField.text ?? "")"

                    completion()
                }
                else {
                    completion(error)
                }
            }
        }
    })
}

上面我们有两个操作:

  • 首先,您更新用户的电子邮件地址。
  • 如果失败,则代码将调用错误的完成处理程序。
  • 如果更新成功,代码将继续更新用户个人资料。
  • 如果更新配置文件更新失败,它将调用完成处理程序并显示错误。
  • 更新成功,它调用不带任何参数的完成处理程序以表明已完成。

由于ref.setValue(...)可以在changeRequest?.commitChanges之前完成,因此这里仍然存在竞争条件。如果这与您的用例有关,则还应该为ref.setValue(...)添加一个完成处理程序,然后从中调用changeRequest?.commitChanges。因此,此时您将有三个顺序操作。