Обновление электронной почты и имени пользователя Firebase в единой функции с обработкой ошибок в swift - PullRequest
0 голосов
/ 09 марта 2019

У меня есть кнопка, где текущий пользователь может обновить свою электронную почту и имя пользователя.

Моя текущая функция

 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)")
            }
        }
    }
}

Подробности обновляются в аутентификации и базе данных, однако этот бит кода никогда не запускается

 if error == nil {
                self.createError(title: "Success", message: "")
            } else {
                self.createError(title: "Error", message: "\(error!.localizedDescription)")
            }

Кто-нибудь знает, почему это не называется?

Спасибо

1 Ответ

0 голосов
/ 09 марта 2019

Пока вы передаете обработчик завершения при вызове 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 из этого.Таким образом, в этот момент у вас будет три последовательных операции.

...