Swift: Auto-Login user with Firebase

i0S Swift Issue

Question or problem in the Swift programming language:

I want to auto-login the user if he is already signed and just head to the main view but the code is running twice and you can see the transistion instead of the view just showing. How do I fix it?

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.slideMenuController
    FIRApp.configure()
    FIRAuth.auth()?.addAuthStateDidChangeListener {
        auth, user in
        if user != nil {
            // User is signed in.
            print("Automatic Sign In: \(user?.email)")

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let initialViewController = storyboard.instantiateViewControllerWithIdentifier("EmployeeRevealViewController")
            self.window!.rootViewController = initialViewController

        } else {
            // No user is signed in.
        }
    }

    return true
}

Log

2016-06-06 01:00:55.585 Untitled[13009:6258910] Configuring the default app.
2016-06-06 01:00:55.657 Untitled[13009:]  Firebase Analytics v.3200000 started
2016-06-06 01:00:55.666 Untitled[13009:]  To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled
2016-06-06 01:00:55.714 Untitled[13009:6258910] Firebase Crash Reporting: Successfully enabled
2016-06-06 01:00:55.739:  FIRInstanceID AppDelegate proxy enabled, will swizzle app delegate remote notification handlers. To disable add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO
2016-06-06 01:00:55.739:  Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
2016-06-06 01:00:55.760:  FIRMessaging library version 1.1.0
2016-06-06 01:00:55.781:  FIRMessaging AppDelegate proxy enabled, will swizzle app delegate remote notification receiver handlers. Add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO
2016-06-06 01:00:55.788 Untitled[13009:]  Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist
Automatic Sign In: Optional("[email protected]")
2016-06-06 01:00:56.759:  APNS Environment in profile: development
Automatic Sign In: Optional("[email protected]")
2016-06-06 01:00:57.811 Untitled[13009:]  Firebase Analytics enabled

How to solve the problem:

Solution 1:

Try:

if let alreadySignedIn = FIRAuth.auth()?.currentUser {
    // segue to main view controller
} else {
    // sign in
}

Solution 2:

As for the updated documentation, this is the recommened way to do it based on the Firebase documentation and it worked for me:

if Auth.auth().currentUser != nil {
  // User is signed in.
  // ...
} else {
  // No user is signed in.
  // ...
}

Firebase changed a but their naming convention, most noticably:

FIRAuth got renamed to Auth

Also for best results, I put this inside the viewDidAppear() like this:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)
    if Auth.auth().currentUser != nil {
        performSegue(withIdentifier: "yourIdentifier", sender: self)
    }
}

Solution 3:

Without identifier for Firebase 4 and swift 4, it worked fine for me…

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)
    if Auth.auth().currentUser != nil {
        let newViewController: YourViewController = YourViewController()
        self.present(newViewController, animated: true, completion: nil)
    }
}

Solution 4:

Use the func “override func viewDidAppear” to instantly log in if user != nil. You also forgot to add “view”, use self.view.window

override func viewDidAppear(_ animated: Bool) {
        if Auth.auth().currentUser != nil {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let initialViewController = storyboard.instantiateViewController(withIdentifier: "homeTabBarVC")
            self.view.window!.rootViewController = initialViewController
        } else { return }
    }

Hope this helps!