Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to login user automatically in iOS swift?

I am using phone authentication using cloud firestore. In firestore db, I am storing user phone number and uid. Here is the code which, I have tried for mobile number login:

  @IBAction func signUp(_ sender: Any) {
    // dismiss keyboard
    view.endEditing(true)   
    if sendOTP == false {
    let mobileNumber = "+91" + phoneNumberTextField.text!

    self.Userdefaults.set(mobileNumber, forKey: "mobileNumber")

    print("mobileNumber::::\(mobileNumber)")

    sendOTPCode()
    sendOTP = true

    } else {

        let codestring = OTPCodeTextField.text

        if codestring?.count == 6 {


            loginusingOTP(OTPtext: codestring!)


        } else {

            print("Enter 6 digit code")

        }

    }


func sendOTPCode() {

    let mymobilenumber = Userdefaults.string(forKey: "mobileNumber")
    PhoneAuthProvider.provider().verifyPhoneNumber(mymobilenumber!) { (verificationID, error) in


            self.Userdefaults.set(verificationID, forKey: "authVerificationID")

            if error != nil
            {
                print ("insde SendCode, there is error")



                print("error: \(String(describing: error?.localizedDescription))")

            } else {
                print ("code sent")


                self.phoneNumberTextField.allowsEditingTextAttributes = false



            }
    }

}

func loginusingOTP(OTPtext: String) {
    let db = Firestore.firestore()
    let verificationID = self.Userdefaults.string(forKey: "authVerificationID")

    let credential: PhoneAuthCredential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID!,
                                                                                  verificationCode: OTPtext)
    Auth.auth().signIn(with: credential)
    {
        (user, error) in
        if error != nil
        {
            print("error: \(String(describing: error?.localizedDescription))")
        }
        else if user != nil
        {

            print("Phone number: \(String(describing: user?.phoneNumber))")
            let userInfo = user?.providerData[0]
            print("Provider ID: \(String(describing: userInfo?.providerID))")

            var _: DocumentReference? = nil

            print("currentUser:::\(String(describing: currentUser))")

            db.collection("users").document(currentUser!).setData([
                "User_Phone_number": user?.phoneNumber as Any,
                "uid": currentUser as Any

            ]) { err in
                if let err = err {
                    print("Error writing document: \(err)")
                } else {
                    print("Document successfully written!")
                    if PrefsManager.sharedinstance.isFirstTime == false{


                        let when = DispatchTime.now() + 0
                        DispatchQueue.main.asyncAfter(deadline: when) {

                            self.performSegue(withIdentifier: "signUpToTabBar", sender: nil)

                        }


                    }else{
                        let when = DispatchTime.now() + 0
                        DispatchQueue.main.asyncAfter(deadline: when) {


                            let storyboard = UIStoryboard(name: "Start", bundle: nil)
                            let initialViewController = storyboard.instantiateViewController(withIdentifier: "onboardvc")
                            self.present(initialViewController, animated: true, completion: nil)

                        }
                    }



                }
            }

        } else {

            print("error::::::")

        }

    }

}

User login flow - First user enter phone number and then taps on send otp then user enters otp code, logged in successfully. Since user login first time, user needs to fill user detail page and then goes to home page. If its already logged in user, after successful of login user will redirected to home screen not the user detail page.

My question is now user is login each and every time to get inside of the app, I want user to login automatically without login each and every time unless user logout. How to check already logged in user UID or phone in cloud firestore for user exist or new user.

Any help much appreciated pls...

like image 934
PvDev Avatar asked Jun 01 '18 04:06

PvDev


3 Answers

Let me give you brief scenario.

SwiftyUserDefaults is the best library to store UserDefaults throughout the app.

Create one extension like this,

extension DefaultsKeys {
    static let username = DefaultsKey<String?>("username")
    static let phoneNo = DefaultsKey<String?>("phoneNo")
    static let islogin = DefaultsKey<Bool?>("islogin")
}

After successful login, you can set the values of the above DefaultKeys like below, first import SwiftyUserDefaults,

Defaults[.username] = Your_User_Name
Defaults[.phoneno] = Your_Phone_No
Defaults[.islogin] = true

Now on your first LoginViewController, in viewDidLoad() method, Please check following,

if Defaults[.islogin] == true {
    //Go to Home with animation false
}

Here you go, let me know in case of any queries.

FYI. This is just the scenario, actual may be different depending on your final requirement. This answer may help you.

like image 175
PPL Avatar answered Nov 15 '22 01:11

PPL


For Firebase (and it looks like FireStore). Once the User is Authenticated on the device, they will automatically be "logged in" to Firebase/Firestore next sessions unless there is a specific SignOut (Auth.auth().signOut()) or unless there is a super long delay (not sure how long, maybe a month).

To check to see if the user is already logged in.

On Start Up (didFinishLaunchingWithOptions) set up an Auth Listener and it will fire once and return the current Auth Status.

func addUserListener() {
    listenHandler = Auth.auth().addStateDidChangeListener { (auth, user) in
        if user == nil {
            // We are Logged Out of Firebase.
            // Move to Login Screen
        } else {
            // we are Logged In to Firebase.
            // Move to Main Screen
        }
  }

You really need to use an Auth Listener for Login calls as if someone has two devices and logs out on one device, they will be logged out of firebase and the 2nd device will crash when you try a firebase call, because it still thinks its logged in.

like image 8
Mark Avatar answered Nov 15 '22 00:11

Mark


Update your login credentials OR loggedIn flag to user Defaults

UserDefaults.standard.set("value", forKey: "username")
UserDefaults.standard.set("value", forKey: "password")

(NB: i recommended not to store password directly, you could store authentication token in Userdefaults, & if you want password to be stored, use keychain instead)

And redirect to corresponding page from AppDelegate:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

   var initialViewController: UIViewController?
    let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    if let username = UserDefaults.standard.value(forKey: "username"), let password = UserDefaults.standard.value(forKey: "password") {
        initialViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeVC")
    } else {
        initialViewController = mainStoryboard.instantiateViewController(withIdentifier: "LoginVC")
    }
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()
   return true
}
like image 3
Lal Krishna Avatar answered Nov 15 '22 02:11

Lal Krishna