Firebase电子邮件验证Swift

时间:2018-07-17 19:10:11

标签: ios swift firebase firebase-authentication

我尝试使用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)
    }
  }
}

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

比@ 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,我强烈建议您使用:)。

答案 2 :(得分:0)

if let email = emailTextfield.text, let password = passwordTextfield.text {
Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
    
    if let e = error{
        print(e.localizedDescription)
    }
    else {
        //Do whatever you want to do after successful login
        
    }
    }
}

答案 3 :(得分:-1)

您也可以尝试以下操作:

   if( !Auth.auth().currentUser!.isEmailVerified) {
    // do something
   }