To begin setting up our project with Firebase we need to setup our project within the Firebase console. I’m not going to cover how to do this here as the documentation does a pretty great job of outlining this. We need to begin by following the instructions to install the Firebase SDK, followed by adding our iOS app to our Firebase project so that we can enable the authentication features for our application.

Now that we have Firebase setup within the console, we need to add the required dependencies to our application. We’re going to do this by adding two declarations to our pod file:

pod 'Firebase/Core'

pod 'Firebase/Auth'

Once these have been added we can go ahead and run pod install so that the Firebase dependencies become available for use in our application.

Now that these are ready for use we’re going to configure Firebase in our application delegate class. Here we need to start by importing the Firebase SDK:

import Firebase

Followed by the call to the configure() function from the SDK. This must be called in-order for us to be able to access Firebase services, because of this we’re going to go ahead and call this within the application function of our delegate to ensure that this is configured at the start-up point of our app:

func application(_ application: UIApplication,

didFinishLaunchingWithOptions launchOptions:

[UIApplicationLaunchOptionsKey: Any]?) -> Bool {

...

FirebaseApp.configure()

...

}

Now that Firebase is configured, we’re ready to use the authentication services that it provides in it’s Auth package. However, before we start diving into triggering the actual authentication flow we’re going to take a look at implementing the auth state listener that Firebase Auth provides. For this we need to begin by declaring a field reference AuthStateDidChangeListenerHandle class:

var handle: AuthStateDidChangeListenerHandle?

This class is a listener which allows us to register for authentication state events on our Firebase Auth instance — allowing us to observe whether or not the user is currently authenticated in our app. We can go ahead and instantiate this listener by using Firebase Auth to retrieve the current auth instance of our Firebase App (using auth()), followed by a call to the addStateDidChangeListener() function:

handle = Auth.auth().addStateDidChangeListener { (auth, user) in

// Handle authenticated state

}

When we call this function we kick off the observation of the authentication state and retrieve back the AuthStateDidChangeListenerHandle. This allows us to keep a reference to our observation and remove the listener during the teardown of our application using the removeStateDidChangeListener() function, passing in our handle reference as an argument:

Auth.auth().removeStateDidChangeListener(handle)

Now that we have the observation configured, we need to actually do something with the data we get back from the listener. In our sample app we’re essentially going to want to show two different states:

A login screen when the user isn’t authenticated

authenticated A home screen when the user is authenticated

So to satisfy this we’re essentially going to set our root view controller based on whether or not the current user from our auth instance is nil or not:

private func observeAuthorisedState() {

self.setupRootViewController(

viewController: SplashViewController()) handle = Auth.auth().addStateDidChangeListener { (auth, user) in

if user == nil {

self.setupRootViewController(

viewController: LoginViewController())

} else {

self.setupRootViewController(

viewController: HomeViewController())

}

}

} private func setupRootViewController(

viewController: UIViewController) {



self.window!.rootViewController = viewController

self.window!.makeKeyAndVisible()

}

Now, whenever the authentication state of our Firebase instance changes our observer will receive the state and set our root view controller based off of this value.