Смена пароля пользователя Firebase и срабатывание метода dismiss


#1

Есть отдельный Controller, в котором 2 поля для ввода нового пароля (ввод и повтор ввода), реализован метод смены пароля через Firebase, в нем реализована проверка на ошибки: не совпадают пароли и короткий пароль меньше 6 символов (надпись ошибки появляется в приложении, активируя warningLable) . Все работает, и смена пароля и проверка ошибок. Но никак не могу понять куда вставить сворачивание экрана self.dismiss(animated: true, completion: nil), в какое бы место не ставил либо функции не все выполняются, либо не сворачивается экран. Поставил точки во всех возможных местах, перепробовал везде, но ничего путного не получается. Логично поставить на точку Point 5, но экран не уходит. Подскажите в чем может быть проблема, может вообще логика метода неправильная.

@IBAction func saveTapped(_ sender: UIButton) {
    if  newPasswordTextField.text == repeatNewPasswordTextField.text  {
        let newPassword = repeatNewPasswordTextField.text
        Auth.auth().currentUser?.updatePassword(to: newPassword!) { error in
            guard error == nil else {
                print(error)
                if let errorCode = AuthErrorCode(rawValue: error!._code) {
                    switch errorCode {
                    case .weakPassword:
                        self.displayWarningLabel(withText: "Короткий пароль. Минимум 6 знаков")
                        print("Point 1")
                    default:
                        print("There is an error")
                         print("Point 2")
                    }
                     print("Point 3")
                }
                 print("Point 4")
                print(error!.localizedDescription)
                return
            }
             print("Point 5")
      // self.dismiss(animated: true, completion: nil)
        }
         print("Point 6")
        } else {
        self.displayWarningLabel(withText: "Пароли не совпадают")
        return
    }
     print("Point 7")
    
    guard let user = self.user else { return }
    guard let credential = self.credential else { return }
    user.reauthenticate(with: credential) { error in
        if let error = error {
            print(error.localizedDescription)
            // An error happened.
        } else {
            print("User re-authenticated")
        }
    }
}

#2

Попробуйте обернуть dismis в DispatchQueue

DispatchQueue.main.async {
    self.dismiss(animated: true)
}

#3

Не помогает. В точке 5 работают все проверки на ошибки, сохраняет новый пароль, но экран не уходит. В точке 6 сохраняет и уходит, но так же уходит экран при попытке ввести короткий пароль, то есть weakPassword не работает. И постоянно в консоле выдает сообщение

This operation is sensitive and requires recent authentication. Log in again before retrying this request.

Хотя вроде reauthenticate реализовал после смены пароля, как и написано в документации


#4

Добавьте в 5 точке return после dismiss.


#5

К сожалению, не работает, проверки проходит на ошибки, пароль сохраняет, но не уходит


#6

Из вашего кода в случае, если ошибки нет, то должно отображаться следующее

  • Point 5
  • Point 6
  • Point 7

Верно?


#7

Последовательность из консоли, если ввожу длинный пароль и пароли совпадают

Point 6
Point 7
Optional(Error Domain=FIRAuthErrorDomain Code=17014 “This operation is sensitive and requires recent authentication. Log in again before retrying this request.” UserInfo={NSLocalizedDescription=This operation is sensitive and requires recent authentication. Log in again before retrying this request., error_name=ERROR_REQUIRES_RECENT_LOGIN})
There is an error
Point 2
Point 3
Point 4
This operation is sensitive and requires recent authentication. Log in again before retrying this request.


#8

А куда пропал Point5?


#9

Вот в этом и вопрос) Сам не понимаю почему так, хотя это логичное место для dismiss


#10

Еще мне кажется я понял в чем у вас проблема.
У вас весь код в методе выполняется асинхронно, т.е. кусок кода после Point 6 выполняется не дожидаясь смены пароля в Firebase. Т.е. по сути у вас всегда быстрее выполняется user.reauthenticate. Не знаю, нужна ли вам такая логика. Если нет, вынесите в отдельный метод этот кусок, уберите Point 6 и 7, а новый метод вызывайте в Point 5 и там уже смотрите когда делать dismiss.


#11

Разобрался. Изменил логику работы. Рабочий код для смены пароля в Firebase, если кому надо

@IBAction func saveTapped(_ sender: UIButton) {
    if  newPasswordTextField.text == repeatNewPasswordTextField.text  {
    guard let email = Auth.auth().currentUser?.email else { return }
    let user = Auth.auth().currentUser
    let credential = EmailAuthProvider.credential(withEmail: email, password: currentPasswordTextField.text!)

    user?.reauthenticate(with: credential, completion: { (error) in
        if error != nil {
            self.displayWarningLabel(withText: "Неверный текущий пароль")
            print("Faild user re-authenticated", error)
        } else {
            print("User re-authenticated")
            //change to new password
            Auth.auth().currentUser?.updatePassword(to: self.repeatNewPasswordTextField.text!) { error in
                guard error == nil else {
                    print(error)
                    if let errorCode = AuthErrorCode(rawValue: error!._code) {
                        switch errorCode {
                        case .weakPassword:
                            self.displayWarningLabel(withText: "Короткий пароль. Минимум 6 знаков")
                        default:
                            print("There is an error")
                        }
                    }
                    print(error!.localizedDescription)
                    return
                }
                self.dismiss(animated: true, completion: nil)
            }
        }
    })
        } else {
        self.displayWarningLabel(withText: "Пароли не совпадают")
        return
    }
}

RexHunt, спасибо за участие!