Search code examples
swiftfirebasefirebase-authenticationswift5

remember user/password and auto login firebase - swift


Hi i have an application that connected to the Firebase and i have two viewController, first viewController is for log in , the second one is a tableViewController. i want to let user log in automatically when they open the application. i mean when they close the Application and open it again i want the Application log in the user automatically. I tried to use firebase documentation in AppDelegate firebase and i tried to use SwiftKeychainWrapper but it didn't help me.

this is my code for the logInController :

import UIKit
import Firebase
import FirebaseAuth
import FirebaseFirestore


class logInViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate {


@IBOutlet var userNameField: UITextField!
@IBOutlet var passwordField: UITextField!
@IBOutlet var logInButton: UIButton!

var db: Firestore!

override func viewDidLoad() {
    
    super.viewDidLoad()
    logInButton.layer.cornerRadius = 4.0
    userNameField.delegate = self
    passwordField.delegate = self
    
    
    
}



@IBAction func logInButtonClicked(_ sender: Any) {
    
    
    Auth.auth().signIn(withEmail: (userNameField.text ?? ""), password: (passwordField.text ?? "")) { (result, error) in
        if let _eror = error{
            let alert = UIAlertController(title: "Error", message: error!.localizedDescription, preferredStyle: .alert)
            let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
            alert.addAction(okAction)
            self.present(alert,animated: true)
            print(_eror.localizedDescription)
        }else{
            
            
            if let _res = result{
                
                print(_res)
                
            }
            
            let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "order1") as! OrderTableViewController
            self.navigationController!.pushViewController(VC1, animated: true)
        }
    }
}
}

this is my AppDelegate code :

class AppDelegate: UIResponder, UIApplicationDelegate {
var db: Firestore!
var firebaseToken: String = ""
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    
    FirebaseApp.configure()
    
    self.registerForFirebaseNotification(application: application)
    Messaging.messaging().delegate = self
    
    
    if Auth.auth().currentUser != nil {
        
        //======
        let homeController = OrderTableViewController()
        self.window?.rootViewController = homeController
        self.window?.makeKeyAndVisible()
        
        
        
    } else {
        
        let logInController = logInViewController()
        self.window?.rootViewController = logInController
        self.window?.makeKeyAndVisible()
        
        
    }
    
    return true
    
}

Solution

  • Firebase already persists the user credentials and restores them when the app restarts. But since this requires a call to the server, it happens asynchronously and probably hasn't completed yet by the time your Auth.auth().currentUser runs.

    The solution is to use an auth state listener, as shown in the first snippet in the documentation on getting the current user:

    handle = Auth.auth().addStateDidChangeListener { (auth, user) in
        if user != nil {
            let homeController = OrderTableViewController()
            self.window?.rootViewController = homeController
            self.window?.makeKeyAndVisible()
        } else {        
            let logInController = logInViewController()
            self.window?.rootViewController = logInController
            self.window?.makeKeyAndVisible()
        }
    }