Firebase Authentication : FirebaseUI and Kotlin

Before now, authenticating users was really a pain in the neck, you would have to design layouts, implement the logic to inputs, make a lot of Stack Overflow searches to implement various log in options for your users. But with Firebase Authentication, Say No More!

Hi, I’m Oluwaleke, welcome back to this series on Firebase! if this is your first time here, please refer to the previous posts here to know how to setup Firebase for your android app.

With Firebase Authentication, you can implement signing in/up with:

  1. Email and Password
  2. Phone number e.g WhatsApp
  3. Google
  4. Facebook
  5. Twitter
  6. GitHub

Sweet thing is, you don’t need to check if the user already exists when he/she attempts to log in. If the account is new, he will be registered. If it’s not, still logs in, no data is lost.
These log in methods are really easy to setup and even far more easier for the user, this really gives a great User eXperience and you don’t need to be lectured on how important that is since this is one of the first screen a users sees in your app.

So less talk, more code! The link to the GitHub repo is here, you should be on the add-authentication branch, that’s where the code of this post is contained.

If you don’t know how to setup firebase for your app, check my previous tutorial here.

PROCEDURE

First, we add our project and app level gradle dependencies,

Project Level Gradle, your gradle version might differ, but for optimal performance, make sure that everything is up to date.

P.S : Don’t forget to implement the lastest Kotlin version in your project

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.1.61'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//Firebase dependency
classpath 'com.google.gms:google-services:3.1.1' // google-services plugin

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

App level build.gradle :::

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.1.61'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//Firebase dependency
classpath 'com.google.gms:google-services:3.1.1' // google-services plugin

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

Sync your project in android studio and we carry on!

SECOND PART : We create a Kotlin activity, let’s call it SignInActivity.

We just write basic XML since FirebaseUI will do the job for us :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/sign_in_container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hashcode.chocshop.activities.SignInActivity">

</RelativeLayout>

Kotlin Code :

Global Variables:

private val RC_SIGN_IN = 123 //the request code could be any Integer
val auth = FirebaseAuth.getInstance()!!

fun showSnackbar(id : Int){
Snackbar.make(findViewById(R.id.sign_in_container), resources.getString(id), Snackbar.LENGTH_LONG).show()
}

FirebaseAuth is the class for implementing anything related to authentication in Firebase. Here we create a variable auth to handle our authentication process. The method showSnackbar() receives an id for a string and displays it.

Your onCreate method should look like this :

auth.currentUser returns a FirebaseUser object if a user is logged in to your app or returns null if not. So if a user is not logged in, we initiate the login flow which is in the else statement.

AuthUI.getInstance() : This shows we are using Firebase UI, so that means we might decide not to do any customisation on our own.

setIsSmartLockEnabled(): FirebaseUI integrates with Smart Lock for Passwords to store and retrieve credentials, enabling automatic and single-tap sign-in to your app for returning users. It also handles tricky use cases like account recovery and account linking that are security sensitive and difficult to implement correctly using the base APIs provided by Firebase Auth.

!BuildConfig.DEBUG : You might not need the SmartLock feature for development, so it’s mostly advisable to use it only in production. So this parameter makes sure the SmartLock feature is only included in production(release) and not development(debug)

setAvailableProviders() : this method receives an array of sign in options and it displays and implements the log in flow respectively as added to the List.
AuthUI.GOOGLE_PROVIDER : for Google sign in
AuthUI.EMAIL_PROVIDER : for email and password sign in or sign up.
You can check out those for other sign in options.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
if(auth.currentUser != null){ //If user is signed in
// startActivity(Next Activity)
}
else {
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(!BuildConfig.DEBUG)
.setAvailableProviders(
Arrays.asList(AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build(),
AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build()))
.setTosUrl("link to app terms and service")
.setPrivacyPolicyUrl("link to app privacy policy")
.build(),
RC_SIGN_IN)
}
}

Then the logic after the user signs in is implemented in the onActivityResult method.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == RC_SIGN_IN){
/*
this checks if the activity result we are getting is for the sign in
as we can have more than activity to be started in our Activity.
*/
val response = IdpResponse.fromResultIntent(data)
if(resultCode == Activity.RESULT_OK){
/*
Checks if the User sign in was successful
*/
// startActivity(Next Activity)
showSnackbar(R.string.signed_in)
finish()
return
}
else {
if(response == null){
//If no response from the Server
showSnackbar(R.string.sign_in_cancelled)
return
}
if(response.errorCode == ErrorCodes.NO_NETWORK){
//If there was a network problem the user's phone
showSnackbar(R.string.no_internet_connection)
return
}
if(response.errorCode == ErrorCodes.UNKNOWN_ERROR){
//If the error cause was unknown
showSnackbar(R.string.unknown_error)
return
}
}
}
showSnackbar(R.string.unknown_sign_in_response) //if the sign in response was unknown
}

NOTE :: This is all you need for the code, but this still won’t if you try to run it, why? Don’t be bothered, you now have to log in to your firebase console and allow the authentication types you need. See below

Enable Email/Password and Google sign in in your firebase console.

Ladies and Gentlemen, that is all that you need to do to implement Firebase Login into your app. If you need to further your knowledge and you need to implement other log in solutions like Facebook and Twitter and also to customise the user interface , kindly refer to the real Firebase documentation.

See you next time as we dig deeper and hotter into Firebase(pun intended, lol) as we will be talking about Firebase Database, Firestore and Storage.

Thank you !

Thank you for reading and I hope I helped someone or two, do well to drop your questions or suggestions in the comment section. Fun Fact :: there’s an icon that looks like two hands just below this post, if you click on it, the number next to it increases. Try it out, I’m surprised too, lol.

--

--

Oluwaleke Fakorede hashCode
Firebase Android with Kotlin Series : ChocShop app

I love sharing my knowledge in the best way. Software || Data Engineer, mathematician.