Create a user with Username, email, and password. Then force the user to complete phone number verification before the account is created.
I am designing an app where we would like to make the user sign up by creating a username, password, supply their email address, and then complete phone number verification.
This picture represents the desired flow we would like our user to complete to register their account.
here are our View Controller files:
This is the code for the "Create Account" view, it creates a user in Firebase using email
import UIKit
class CreateAccountVC: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var usernameTextfield: UITextField!
@IBOutlet weak var passwordTextfield: UITextField!
@IBOutlet weak var emailTextfield: UITextField!
@IBOutlet weak var confirmPasswordTextfield: UITextField!
@IBOutlet weak var createAccountLbl: UILabel!
@IBOutlet weak var createAccountTextView: UILabel!
@IBOutlet weak var signupBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:UIResponder.keyboardWillHideNotification, object: nil)
overrideUserInterfaceStyle = .light
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
signupBtn.clipsToBounds = true
signupBtn.layer.cornerRadius = 15
signupBtn.addButtonGradient(didType: true)
}
@objc func keyboardWillShow(notification:NSNotification){
let userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.scrollView.contentInset
contentInset.bottom = keyboardFrame.size.height
scrollView.contentInset = contentInset
}
@objc func keyboardWillHide(notification:NSNotification){
let contentInset:UIEdgeInsets = UIEdgeInsets.zero
scrollView.contentInset = contentInset
}
@IBAction func alreadyHaveAccountBtnPressed(_ sender: Any) {
// dismiss(animated: true, completion: nil)
// self.performSegue(withIdentifier: "TypePhoneNumberVC", sender: self)
}
@IBAction func signupBtnPressed(_ sender: Any) {
let username = usernameTextfield.text
let email = emailTextfield.text
let password = passwordTextfield.text
signupBtn.isHidden = true
AuthorizationService.instance.registerUser(username: username!, email: email!, password: password!) { (success, err) in
if success{
AuthorizationService.instance.loginUser(withEmail: email!, andPassword: password!) { (success, err) in
if err != nil{
return
}
self.performSegue(withIdentifier: "EnterNumberSegue", sender: self)
print("Sign-up successful")
}
}else{
let alertController = UIAlertController(title: "Error", message: err?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
self.signupBtn.isHidden = false
}
}
}
@IBAction func backBtnPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
These next two demonstrate the implementation of the Phone number verification
import UIKit
import Firebase
import FirebaseAuth
class EnterPhoneNumberVC: UIViewController, UITextFieldDelegate{
@IBOutlet weak var backButton: UIButton!
@IBOutlet weak var phoneNumberUITextField: UITextField!
@IBOutlet weak var getCodeButton: UIButton!
let userDefaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
phoneNumberUITextField.delegate = self
let tap = UITapGestureRecognizer(target: self, action: #selector(handle))
view.addGestureRecognizer(tap)
overrideUserInterfaceStyle = .light
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getCodeButton.clipsToBounds = true
getCodeButton.layer.cornerRadius = 15
getCodeButton.addButtonGradient(didType: true)
}
@objc func handle(tap: UITapGestureRecognizer){
view.endEditing(true)
}
@IBAction func backButtonPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
@IBAction func getCodeButtonPressed(_ sender: Any) {
guard let phoneNumber = phoneNumberUITextField.text else {return}
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
if error == nil {
print(verificationID)
guard let verifyID = verificationID else {return}
self.userDefaults.set(verifyID, forKey:"verificationID")
self.userDefaults.synchronize()
self.performSegue(withIdentifier: "GetCodeSegue", sender: self)
} else {
print("unable to confirm the users phone number", error?.localizedDescription)
}
}
}
import UIKit
import Firebase
import FirebaseAuth
class PhoneNumberVerificationVC: UIViewController, UITextFieldDelegate {
@IBOutlet weak var verifyBtn: UIButton!
@IBOutlet weak var resendCodeBtn: UIButton!
@IBOutlet weak var otpCode: UITextField!
var verificationID: String?
let userDefaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
overrideUserInterfaceStyle = .light
let tap = UITapGestureRecognizer(target: self, action: #selector(handle))
view.addGestureRecognizer(tap)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
verifyBtn.clipsToBounds = true
verifyBtn.layer.cornerRadius = 15
verifyBtn.addButtonGradient(didType: true)
}
@objc func handle(tap: UITapGestureRecognizer){
view.endEditing(true)
}
@IBAction func backBtnPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
@IBAction func verifyBtnPressed(_ sender: Any) {
guard let optCode = otpCode.text else {return}
guard let verificationID = userDefaults.string(forKey: "verificationID") else {return}
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID, verificationCode: optCode)
Auth.auth().signInAndRetrieveData(with: credential) { (success, error) in
if error == nil {
print(success)
self.performSegue(withIdentifier: "VerifiedSegue", sender: self)
print("The user has successfully logged In and is verified!")
} else {
print("Error: Phone number and One time password does not match")
}
}
}