Firebase Authentication with Coroutines in Kotlin (2022)

Hello, Developers in this post, we are going to learn and implement a signup, login, and logout functionality using Firebase Authentication with Coroutines in Kotlin. Firebase helps to develop for building high-quality apps and that feature works independently . Firebase is one of the largest account databases in the world and it provides an end-to-end identity solution, supporting email and password accounts, phone auth, and Google, Twitter, Facebook, GitHub login, and more It’s a very secure authentication system.

Let’s build a user Authentication with Kotlin Coroutines in Android 2022 using Firebase. Firebase provides a full set of authentication and it automatically stores users’ credentials securely with the help of bcrypt. So without any further, discuss let’s get started.

Firebase Authentication with Coroutines in Kotlin

Follow Firebase for Android playlist on youtube – Firebase for Android

Step 1: Add your project with Firebase

Before going further add your project with firebase, follow this article step by step – Getting started with Firebase on Android (2022)

Step 2: Add the required library

Add the required library for Firebase Authentication and Coroutines.

build.gradle (Module)
 /* Import the Firebase BoM */
    implementation platform('com.google.firebase:firebase-bom:30.1.0')
    implementation 'com.google.firebase:firebase-analytics-ktx'

    /* Firebase Authentication */
    implementation 'com.google.firebase:firebase-auth-ktx:21.0.5'

    /*	coroutines support for firebase operations */
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.0'

    /*	Lifecycle-aware coroutine scopes */
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'

Step 3: Simple UI for the Signup, Login, and Logout

Create a simple UI for the signup, login, and logout to get the email id and password from the user.

activity_signup_signin
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:layout_margin="16dp">

    <ProgressBar
        android:id="@+id/progress_circular"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/edtEmailID"
        app:layout_constraintEnd_toEndOf="parent"
        android:visibility="gone"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Firebase Authentication"
        android:textColor="@color/purple_500"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/edtEmailID"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#F4F4F4"
        android:hint="Enter email id"
        android:paddingStart="4dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline" />

    <EditText
        android:id="@+id/edtPassword"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="8dp"
        android:background="#F4F4F4"
        android:hint="Enter password"
        android:paddingStart="4dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/edtEmailID" />

    <Button
        android:id="@+id/btnSignUp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Sign up"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/edtPassword" />

    <Button
        android:id="@+id/btnSignIn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Sign in"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnSignUp" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.4" />

</androidx.constraintlayout.widget.ConstraintLayout>
activity_main

This XML code is responsible to create the main screen AKA Dashboard Screen

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">

    <TextView
        android:id="@+id/loginBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Dashboard"
        android:textColor="@color/purple_500"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnSignOut"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Logout"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginBtn" />
</androidx.constraintlayout.widget.ConstraintLayout>

Step 4: Write Authentication Logic

Now is the time to write the logic for Authentication (Signup and Login) with Kotlin Coroutines

SignUpSignInActivity.kt
package com.techpassmaster.firebasecourse

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.google.firebase.auth.AuthResult
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext

class SignUpSignInActivity : AppCompatActivity() {

    private lateinit var edtEmailId : EditText
    private lateinit var edtPassword : EditText

    private lateinit var btnSignUp : Button
    private lateinit var btnSignIn : Button

    private lateinit var mAuth: FirebaseAuth
    private lateinit var progressBar: ProgressBar

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_signup_signin)

        edtEmailId = findViewById(R.id.edtEmailID)
        edtPassword = findViewById(R.id.edtPassword)
        btnSignUp = findViewById(R.id.btnSignUp)
        btnSignIn = findViewById(R.id.btnSignIn)
        progressBar = findViewById(R.id.progress_circular)

        mAuth = FirebaseAuth.getInstance()


        btnSignUp.setOnClickListener {

            progressBar.visibility = View.VISIBLE

            val emailId = edtEmailId.text.toString()
            val password = edtPassword.text.toString()

            lifecycleScope.launch(Dispatchers.IO){
                signUpWithEmailAndPassword(mAuth,emailId,password)
            }
        }

        btnSignIn.setOnClickListener {

            progressBar.visibility = View.VISIBLE

            val emailId = edtEmailId.text.toString()
            val password = edtPassword.text.toString()

            lifecycleScope.launch(Dispatchers.IO){
                signInWithEmailAndPassword(mAuth,emailId,password)
            }
        }

    }

    suspend fun signUpWithEmailAndPassword(
        firebaseAuth: FirebaseAuth,
        emailId: String,
        password: String) :AuthResult? {

        return try {
            val result = firebaseAuth.createUserWithEmailAndPassword(emailId,password)
                .await()

            updateUI(result.user)

            result
        } catch (e :Exception){
            withContext(Dispatchers.Main){
                Toast.makeText(this@SignUpSignInActivity, "${e.message}", Toast.LENGTH_SHORT).show()
                Log.d("AuthResult","${e.message}")
                progressBar.visibility = View.GONE
            }
            null
        }
    }

    suspend fun signInWithEmailAndPassword(
        firebaseAuth: FirebaseAuth,
        emailId: String,
        password: String) :AuthResult? {

        return try {
            val result = firebaseAuth.signInWithEmailAndPassword(emailId,password)
                .await()

            updateUI(result.user)
            result
        } catch (e :Exception){
            withContext(Dispatchers.Main){
                Toast.makeText(this@SignUpSignInActivity, "${e.message}", Toast.LENGTH_SHORT).show()
                Log.d("AuthResult","${e.message}")
                progressBar.visibility = View.GONE
            }
            null
        }
    }

    private suspend fun updateUI(firebaseUser :FirebaseUser?) {
        Log.d("AuthResult","${firebaseUser?.email}")

        withContext(Dispatchers.Main){
            progressBar.visibility = View.GONE
            Toast.makeText(this@SignUpSignInActivity, "Success", Toast.LENGTH_SHORT).show()
            startActivity(Intent(this@SignUpSignInActivity, MainActivity::class.java))
            finish()
        }
    }

    override fun onStart() {
        super.onStart()

        val currentUser = mAuth.currentUser
        if (currentUser!=null){
            startActivity(Intent(this@SignUpSignInActivity, MainActivity::class.java))
            finish()
        }
    }
}
MainActivity.kt

In this activity, we will implement logout functionality

package com.techpassmaster.firebasecourse

import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth

class MainActivity : AppCompatActivity() {

    private lateinit var btnSignOut :Button
    private lateinit var mAuth : FirebaseAuth

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btnSignOut = findViewById(R.id.btnSignOut)
        mAuth = FirebaseAuth.getInstance()

        btnSignOut.setOnClickListener {
            mAuth.signOut()
            Toast.makeText(this, "SignOut Successful", Toast.LENGTH_SHORT).show()
            finish()
        }
    }
}

Step 5: Run and Test Authentication

-Final Output-

Techpass Master

Techpass Master is a website for free Android App Development, Java, Kotlin, Jetpack Compose, Firebase, & other tech tips & tricks tutorials. We focus on posting the article at Android App Development. Apart from App development tutorials, we also occasionally post other technology tips and tricks, which can be very helpful for you. Stay tuned with Techpass Master for more updates.
View All Articles

Leave a Reply

Your email address will not be published.