3

For my iOS app, I am currently checking if a user is logged in with email and password via firebase in my initial view controller, using the recommended method from the firebase documentation. If a user is not logged in, I then present my login screen as shown below:

class InitialViewController: UIViewController {

    var authHandle: FIRAuthStateDidChangeListenerHandle!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        hasUserSignedIn()
    }

    func hasUserSignedIn() {

        authHandle = FIRAuth.auth()?.addStateDidChangeListener { [unowned self] auth, user in

        if user == nil {
            self.perform(#selector(self.presentLogInSignUp), with: nil, afterDelay: 0)
        } 
    }

}

However, when a user is not signed in, they briefly see my initial view controller before the log in controller is presented, which isn't a great user experience. A way to solve this would be to add a check in the app delegate's didFinishLaunchingWithOptions.

Firstly, is the app delegate and didFinishLaunchingWithOptions an OK place to check if a user is logged in with Firebase (would be done after FIRAppConfigure())?. I assume it is, as from my understanding, a user's Firebase logged in state is persisted in the keychain (is that correct?)

Secondly, if the app delegate is an appropriate place for checking a user's logged in state, should I use the recommended way as I do in my initial view controller or the method below? The advantage of latter is that I don't need to worry about having to remove a listener but Firebase docs gives a warning with this method that the auth object may not have finished initialising.

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

Current potential solution: I use the recommended method in didFinishLaunchingWithOptions and I just remove the handler after using it within didFinishLaunchingWithOptions.

Firebase is awesome and look forward to implementing this correctly.

Edward
  • 2,864
  • 2
  • 29
  • 39
  • 1
    Possible duplicate of [Checking Firebase current signed-in user via Listener in iOS](https://stackoverflow.com/questions/41531271/checking-firebase-current-signed-in-user-via-listener-in-ios) – Kqtr Jul 14 '17 at 19:11

2 Answers2

1

they briefly see my initial view controller

They are not seeing the initial view controller. They are seeing the view that the initial view controller is controlling. i.e. by the time the code gets to viewWillAppear the view has already been loaded and is ready to be shown which is why it's initially visible before changing to the log in view.

The logic to determine which view should be shown should occur before then.

One option is to determine that in the app delegate and instantiate the appropriate viewController in code in the didFinishLaunchingWithOptions function.

If you look at your Main.storyboard, click the view and then on the right in the attributes inspector, there's a checkbox for Is Initial View Controller. That's the first one to be displayed. If you uncheck that, then you can set it up in code.

See this question and answer

Programmatically set the initial view controller using Storyboards

Jay
  • 34,438
  • 18
  • 52
  • 81
0

You can do the check in didFinishLaunchingWithOptions, or viewDidLoad....

Or... alternatively, for anyone who want to keep it in viewWillAppear, because you may have to do that anyway. For example if the user gets their email verified and you come back to the same page, you may have to reaload the user and check isEmailVerified inside of viewWillAppear.

So one way of showing different controllers in general is to embed them in a customised UITabBarController, make sure to hide the actual bar of cause. You can then check the "Auth.auth().currentUser" in the viewWillAppear of the customised UITabBarController and select the page you want to show conditionally (with self.selectedIndex = whatever and make sure not to animate the transition).

I guess the advantage of doing it this way is the flow is clear and if you use the storyboard it's nice and tidy.

lzl
  • 469
  • 4
  • 10