Firebase电子邮件验证Swift

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Firebase电子邮件验证Swift相关的知识,希望对你有一定的参考价值。

我曾尝试使用Firebase身份验证,但是即使我没有使用电子邮件来确认验证,也可以通过登录名登录。我有两个Viewcontroller,一个用于登录,另一个用于signUP。我可以登录并获取电子邮件进行验证,但也可以不进行验证就登录。

public func sendVerificationMail() {
  if self.authUser != nil && !self.authUser!.isEmailVerified {
    self.authUser!.sendEmailVerification(completion: { (error) in
      // Notify the user that the mail has sent or couldn't because of an error.
    })
  } else {
    // Either the user is not available, or the user is already verified.
  }
}

@IBAction func signupButtonTapped(_ sender: Any) {
  print("Sign up button tapped")
  Auth.auth().createUser(withEmail: self.userEmailTextField.text!, password: self.userPasswordTextField.text!) { (user, error) in
    if user != nil {
      print("User has Signed Up")
      self.sendVerificationMail()    
    }
    if error != nil {
      print("User cant Sign Up")
    }
  }
}

@IBAction func signinButtonTapped(_ sender: Any) {
  Auth.auth().signIn(withEmail: self.userEmailTextField.text!, password: self.userPasswordTextField.text!) { (user, error) in
    if user != nil {
      print("User has Signed In") 
    }
    if error != nil {
      print("Cant Sign in user")
    } else {
      self.performSegue(withIdentifier: "toHome", sender: nil)
    }
  }
}
答案

Firebase Auth不会阻止人们在未验证其电子邮件时登录。如果要防止未经验证的用户前进,则需要使用isEmailVerified布尔值在客户端上对此进行编码。

Auth.auth().signIn(withEmail: self.userEmailTextField.text!, password: self.userPasswordTextField.text!) { (authResult, error) in
  if let authResult = authResult {
    let user = authResult.user
    print("User has Signed In")
    if user.isEmailVerified {
      self.performSegue(withIdentifier: "toHome", sender: nil)
    } else {
      // do whatever you want to do when user isn't verified
    }
  }
  if let error = error {
    print("Cant Sign in user")
  }
}
另一答案

比@ jen-person提供的解决方案更全面的解决方案(并与另一个SO答案一起基于:):>

final class MySignInView: UIView { // or possibly MySignInViewController: UIViewController

    // ... your properties etc...

    @IBAction func signInButtonPressed(sender _: AnyObject) {
        trySigningIn()
    }

}

// MARK: Private
private extension MySignInView {

    func trySigningIn() {
        guard 
            let email = userEmailTextField.text,
            let password = userPasswordTextField.text
        else {
            print("Cannot sign in, email or password is 'nil'")
            return
        }

        do {
            try signIn(email: email, password: password) { [unowned self] authResult in
                self.userDidSignIn(authResult.user)
            }
        } catch {
            // Display error
        }
    }

    func userDidSignIn(_ user: FIRUser) {
        // Creds to Jen: https://stackoverflow.com/a/51389154/1311272
        guard user.isEmailVerified else {
            // TODO display message about non verified email user?
            return
        }
        performSegue(withIdentifier: "toHome", sender: nil)
    }
}

// MARK: Error
private extension MySignInView {
    enum Error: Strng, Equatable {
        case invalidEmail
        case userDisabled
        case wrongPassword
        case userNotFound
        case networkError
        case unknownError
    }
}

// MARK: Firebae specific
private extension MySignInView {

    func signIn(
        email: String, 
        password: String, 
        onSuccessful: (AuthDataResult) -> Void
    ) throws {

        Auth.auth().signIn(
            withEmail: email, 
            password: password
        ) { (authResult, anyError) in
            if let anyError = anyError {
                if let error = Error(anyError: anyError) {
                    throw error
                } else {
                    fatalError("Unsupported error: (anyError)")
                }
            }
            onSuccessful(authResult)
        }
    }
}

private extension MySignInView.Error {

    init?(anyError: Swift.Error) {
        guard let authErrorCode = FIRAuthErrorCode(rawValue: anyError.code) else {
            return nil
        }
        self.init(fireBaseAuthErrorCode: authErrorCode)
    }

    // Creds goes to to: https://stackoverflow.com/a/39936083/1311272
    init(fireBaseAuthErrorCode: FIRAuthErrorCode) {
        switch errCode {
        case .ErrorCodeInvalidEmail:
            self = .invalidEmail
        case .ErrorCodeUserDisabled:
            self = .userDisabled
        case .ErrorCodeWrongPassword:
            self = .wrongPassword
        case .ErrorCodeUserNotFound:
            self = .userNotFound
        case .ErrorCodeNetworkError:
            self = .networkError
        default:
            self = .unknownError
        }
    }
}

您需要适当地通知用户有关错误/错误状态的信息,而不仅仅是打印。

此代码可能应该转移到ViewModel,如果您不使用MVVM,我强烈建议您使用:)。

另一答案

您也可以尝试以下操作:

以上是关于Firebase电子邮件验证Swift的主要内容,如果未能解决你的问题,请参考以下文章

无法重新授权用户更改电子邮件或重置密码(Firebase .. Swift)

如何通过 iOS(swift)将 Firebase Auth 与 MySQL DB 同步?

Swift iOS Firebase - 如果FirebaseAuth.FIRUser对象不是nil,它上面的.email怎么可能返回nil?

Swift Firebase 函数错误:NSCocoaErrorDomain

Expo - Firebase 电子邮件验证

如何使用 Swift 使用此代码片段为 iOS 应用程序初始化 SDK?