Exploring Firebase UI on Android: Authentication

Firebase UI provides us with a collection of utilities that make it easier to implement common UI components within applications. Firebase authentication provides us a way for our users to validate their identity, without the need to implement all of the back-end work ourselves. hen compared to interacting with the authentication APIs directly, Firebase Authentication UI handles a lot of things for us out of the box:

  • All API request required to communicate with Firebase Authentication services
  • All of the UI around authentication for each of the different service providers (email signup forms, phone number verification etc)
  • Automatic handling of user account creation and connection, as well as the linking of accounts from different providers
  • Automatic integration with Google smart lock

This allows us to authenticate users through a number of different methods, providing us with both variety and flexibility when it comes to authentication within our applications. Throughout this post I want to dive into the Authentication UI so that you can make use of it within your own applications.


Configuring Firebase UI

When it comes to implementing Firebase UI, we need to begin by declaring the supported methods of authentication. Firebase will then show a button for each of these methods within the launched authentication screen. The current methods of authentication that Firebase support via its UI library are email, phone, Google, Twitter and Facebook.

Once you have decided the authentication methods which are to be accepted by your application, you can create a list of them ready for use with the Firebase Auth UI builder:

val providers = arrayListOf(
    AuthUI.IdpConfig.EmailBuilder().build(),
    AuthUI.IdpConfig.PhoneBuilder().build(),
    AuthUI.IdpConfig.GoogleBuilder().build(),
    AuthUI.IdpConfig.FacebookBuilder().build(),
    AuthUI.IdpConfig.TwitterBuilder().build()
)

For simplicity in this article, we’re only going to focus on Email, Phone and Google authentication.

Note: Before attempting to use any of the authentication providers, you need to be sure to enabled them from within the firebase console.

Triggering the Authentication flow

Now that we have our supported authentication methods, we can go ahead and make use of them when launching our authentication screen. We’ll begin here by declaring a request code — we need to do this so that once the authentication process has completed and Firebase Authentication returns data to our Activity, we have a way of picking up this data via a unique request code.

private val RC_SIGN_IN = 1822

The Firebase Authentication UI library contains an activity which handles the authentication process for us — this means that we need to a) launch this activity and b) listen for the result that is to be returned by it using our unique request code. For this, we’ll make use of the createSignInIntentBuilder() from our AuthUI instance — triggering the intent when our desired button is pressed.

button_authenticate.setOnClickListener {
startActivityForResult(
        AuthUI.getInstance()
            .createSignInIntentBuilder()
            .setAvailableProviders(providers)
            .build(),
        RC_SIGN_IN
    )
}

If you launch your activity and hit the authentication button, then you will be shown a screen similar to this, listing the available authentication options:

We can also further customise this screen to display additional content alongside the authentication buttons. For example, we may want to show a logo to add a touch of our brand to the authentication screen. We can do so by making use of the setLogo() function on our AuthUI instance.

private fun setupAuthenticateListener() {
    button_authenticate.setOnClickListener {
        startActivityForResult(
            AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setAvailableProviders(providers)
                .setLogo(R.drawable.ic_logo)
                .build(),
            RC_SIGN_IN
        )
    }
}

We can also set a theme to be used for Firebase UI authentication screens. By default your application theme will be used (such as the primary color etc). But if you want further customisation, then you can do so by using the setTheme() function on the AuthUI instance.

private fun setupAuthenticateListener() {
    button_authenticate.setOnClickListener {
        startActivityForResult(
            AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setAvailableProviders(providers)
                .setTheme(R.style.AuthenticationTheme)
                .build(),
            RC_SIGN_IN
         )
    }
}
<style name=”AuthenticationTheme” parent=”FirebaseUI”>
    <item name=”windowActionBar”>false</item>
    <item name=”windowNoTitle”>true</item>
    <item name=”colorPrimary”>@color/someGreen</item>
    <item name=”colorPrimaryDark”>@color/anotherGreen</item>
    <item name=”colorAccent”>@color/purple</item>
    <item name=”colorControlNormal”>@color/someGreen</item>
    <item name=”colorControlActivated”>@color/anotherGreen</item>
    <item name=”colorControlHighlight”>@color/purple</item>
</style>

Finally, the AuthUI instance allows us to provide links to our privacy policy and terms of service. When these are provided, links will automatically be displayed at the footer of our authentication screen.

private fun setupAuthenticateListener() {
    button_authenticate.setOnClickListener {
        startActivityForResult(
            AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setAvailableProviders(providers)
                .setTosAndPrivacyPolicyUrls(
                    “https://joebirch.co/terms.html”,
                    “https://joebirch.co/privacy.html”)
                .build(),
            RC_SIGN_IN
        )
    }
}

Note: When you apply any of the above customisations, it’s likely that the screen will begin to fill. When this happens, the authentication provider buttons will automatically show scrollbars for their container — allowing your screen to scale across different form factors.


Email Authentication

Email authentication allows our users to sign up / in to our service via the use of a chosen email address. When it comes to Firebase UI we get presented with a simple flow which allows our users to make use of any Google accounts which may have been connected on the device:

After hitting the sign in with email button the email authentication screen is launched. At this point an overlay is displayed which lists the auto-fill accounts on the mobile device — this allows the users to pre-fill email and name fields automatically from one of these accounts. Selecting None of the above will take the user to enter these pieces of information one-by-one.

You’ll also notice here that the service and policy links that were originally set are also displayed here. Once the user continues and saves their data they will be returned to the main authentication screen where you will need to handle the authentication response inside of onActivityResult().


Phone Authentication

Phone authentication provides a way for our users to easily connect via the use of a phone number. Here the Firebase UI provides a country code selector (which in itself saves a ton of work!) alongside a field for the phone number entry — you’ll notice here that the terms and policy links are also displayed.

Once the user has entered their phone number they will be sent a verification code, they’ll need to enter this on the next screen that is presented to them. Firebase UI also handles the timed display of a resend-code functionality which you can see on the third screenshot below:

Once the user has entered the verification code they will be returned to the main authentication screen where you will need to handle the authentication response inside of onActivityResult().


Google Authentication

Once the users Google account connection has completed they will be returned to the main authentication screen where you will need to handle the authentication response inside of onActivityResult().


Signing out the current user

We can sign out the currently authenticated user when they choose to end their session in our app. Here we simply fetch our AuthUI instance and call the signOut() function on it. We can set various listeners on this action,
here we’re just going to add an OnCompleteListener — this allows us to listen for a completion event on the signOut action and determine whether or not the action was successful. At this point you can return the user to the authentication screen and handle any other actions that your app may require to perform during sign-out.

private fun signOut() {
    AuthUI.getInstance()
        .signOut(this)
        .addOnCompleteListener { }
}

Deleting the currently authenticated user

We can also delete the currently authenticated user when they choose to end their session in our app. Here we simply fetch our AuthUI instance and call the delete() function on it. We can set various listeners on this action,
here we’re just going to add an OnCompleteListener — this allows us to listen for a completion event on the signOut action and determine whether or not the action was successful. At this point you can return the user to the authentication screen and handle any other actions that your app may require to perform during sign-out.

private fun deleteUser() {
    AuthUI.getInstance()
        .delete(this)
        .addOnCompleteListener { }
}

As you can see from the above, Firebase UI for Authentication provides us with a way to quickly and easily implement authentication for our applications with Firebase. Whether you’re working on a side-project, a production level app or are already making use of Firebase Authentication — this UI library offers many pieces of functionality to streamline both the developer and user experience. Have any questions? Feel free to reach out if so!