Complete User Authentication System with Android Studio and Firebase

Hello friend, I hope you are well. Today, we are starting a login system using Firebase authentication. Before we proceed to perform CRUD operations using Firebase Realtime Database, we are creating a simple login system or app. We will not only create a login page but also implement user registration, login, logout, forgot password, and delete account functionalities.

Yes, this is a full tutorial on a user login system in which we cover various topics like user registration, login, password recovery, logout, and the addition of a delete account feature. All these steps are covered in this tutorial.

Without further introduction, let’s start the tutorial. We will perform all tasks in Android Studio and Firebase Console. If you are not logged into Firebase, please log in. If you are unfamiliar with Firebase, watch the tutorial before this one, which explains in detail how to connect Android to Firebase. You can find both tutorials for manual and automatic connections.

Let’s get to the point and understand this login page step by step. If you have any questions or need clarification, feel free to ask!

Step 1: Create a Project

Begin by creating a new project in Android Studio.

Step 2: Splash Screen

Following the project creation, let’s initiate our app with a splash screen. Ensure to update the intent filter in your AndroidManifest file. By default, the intent filter points to your MainActivity. If you’ve created a new splash screen activity and wish to open the main activity first, you should manually replace the intent filter from MainActivity to SplashScreenActivity.

Now, let’s design the UI for our splash screen. Here, we’ll create a simple XML layout for illustration purposes.

activity_splash.xml

<?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=".SplashActivity">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_launcher_background" />
</androidx.constraintlayout.widget.ConstraintLayout>

Backend Code for Splash Screen

Next, let’s implement the backend code for the splash screen. In this code, we’ll not only handle the splash screen but also implement Authentication Status.

SplashActivity.kt

class SplashActivity : AppCompatActivity() {
    private lateinit var auth: FirebaseAuth
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        auth=FirebaseAuth.getInstance()
        //check authenticate status
        val currentUser=auth.currentUser
        Handler().postDelayed({
            //if user before login,and not logout then shwoing welcome page mean Mainactivity
            if(currentUser==null){
                //navigate second activity
                val intent=Intent(this,LoginActivity::class.java)
                startActivity(intent)
            }else{
                //fi user authenticate, navigate MainActivity
                val mintent=Intent(this,MainActivity::class.java)
                startActivity(mintent)
            }
            finish()
        },3000)//3 seconds
    }
}

Explanation

This code is for a SplashActivity, which is typically a screen that appears briefly when the app is launched. It often displays the app logo or some introductory content before redirecting the user to the main part of the application.

Setting Up Firebase Authentication

auth = FirebaseAuth.getInstance()

It initializes the FirebaseAuth instance.

Checking Authentication Status

val currentUser = auth.currentUser

It checks if there is a currently authenticated user. If there is a user, currentUser will contain the user information; otherwise, it will be null.

Delayed Execution with Handler

Handler().postDelayed({
    // ...
}, 3000) // 3 seconds

It uses a Handler to delay the execution of the code inside the run block for 3 seconds. This delay simulates a splash screen display.

Conditional Navigation

if (currentUser == null) {
    
    val intent = Intent(this, LoginActivity::class.java)
    startActivity(intent)
} else {
    
    val mintent = Intent(this, MainActivity::class.java)
    startActivity(mintent)
}

After the delay, it checks whether there is a currently authenticated user (currentUser). If there is no authenticated user (currentUser == null), it navigates to the LoginActivity. If there is an authenticated user, it navigates to the MainActivity.

Finish the Activity

finish()

It finishes the SplashActivity to prevent it from appearing when the user presses the back button.

In summary, this code creates a splash screen that checks if a user is already authenticated. If there is an authenticated user, it directly navigates to the MainActivity; otherwise, it goes to the LoginActivity. The splash screen is displayed for 3 seconds before the redirection.

Step 3: Connect with Firebase

Before we begin creating the registration screen, it’s essential to establish a connection between Firebase and Android Studio. This connection can be established manually or automatically. If you’re unfamiliar with the process, you can refer to video tutorials for detailed guidance.

In this tutorial, we’ll connect Android Studio to Firebase using the automatic method. Here are the steps:

  • In Android Studio, navigate to Tools and click on Firebase.
  • Open the sidebar panel and select Authentication.
  • Click on Authenticate using a custom authentication system.
  • Connect your app to Firebase by clicking on Connect. This action redirects you to the Firebase Console page.

Once the connection is complete, proceed to add the Firebase Authentication SDK to your app.

All set! Now, navigate to Firebase, select your project, and go to the ‘Build’ section. Click on ‘Authentication’ and then select ‘Get Started.’ Choose ‘Email/Password’ as we’re utilizing email and password authentication. You’ll find various options here. Enable ‘Email/Password,’ and don’t forget to click the ‘Save’ button.

Step 4: Registration Screen

Let’s move on to creating the registration activity. Follow these steps:

Create a new activity named `RegisterActivity`.

Go to activity register.xml layout and add the following code

activity_register.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".RegisterActivity">
    <EditText
        android:id="@+id/editTextEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Enter Email"
        android:inputType="textEmailAddress" />
    <EditText
        android:id="@+id/editTextPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/editTextEmail"
        android:ems="10"
        android:hint="Enter password"
        android:inputType="textPassword" />
    <Button
        android:id="@+id/Regibutton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/editTextPassword"
        android:text="Register" />
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/registerProgressbar"
        android:visibility="gone"
        android:layout_centerInParent="true"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@id/Regibutton">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginStart="5dp"
            android:text="Already have an Account? "/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Login Now."
            android:layout_marginTop="10dp"
            android:id="@+id/loginActivityRedirect"
            android:textColor="@android:color/holo_blue_dark"/>
    </LinearLayout>
</RelativeLayout>

Next add backend  code RegisterActivity

RegisterActivity.kt

class RegisterActivity : AppCompatActivity() {
    private lateinit var editRegiEmail:EditText
    private lateinit var editRegiPassword:EditText
    private lateinit var regiBtn:Button
    private lateinit var redirectLogin:TextView
    private lateinit var registerProgressbar:ProgressBar
    private lateinit var auth: FirebaseAuth
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_register)
        //create instance
        auth=FirebaseAuth.getInstance()
        //find id
        findId()
        createUser()
        redirectLoginPage()
    }
    private fun redirectLoginPage() {
        redirectLogin.setOnClickListener {
            startActivity(Intent(this,LoginActivity::class.java))
        }
    }
    private fun createUser() {
        regiBtn.setOnClickListener{
            val email=editRegiEmail.text.toString().trim()
            val password=editRegiPassword.text.toString().trim()
            // check field is not empty
            if (email.isNotEmpty() && password.isNotEmpty()){
                //display progressbar
                registerProgressbar.visibility= View.VISIBLE
                auth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(this){task->
                    //hide the progressbar
                    registerProgressbar.visibility=View.INVISIBLE
                    if (task.isSuccessful){
                        //show success message
                        Toast.makeText(this,"Registration successful",Toast.LENGTH_LONG).show()
                        //after success registration navigate login activity or other activity
                        val intent= Intent(this@RegisterActivity, LoginActivity::class.java)
                        startActivity(intent)
                        finish()
                    }else{
                        //handle registration failed message
                        Toast.makeText(this,"Registration failed:${task.exception?.message}",Toast.LENGTH_LONG).show()
                    }
                }
            }else{
                //if user email and password filed empty
                Toast.makeText(this,"Please Enter Email and password",Toast.LENGTH_LONG).show()
            }
        }
    }
    private fun findId() {
       editRegiEmail=findViewById(R.id.editTextEmail)
        editRegiPassword=findViewById(R.id.editTextPassword)
        regiBtn=findViewById(R.id.Regibutton)
        redirectLogin=findViewById(R.id.loginActivityRedirect)
        registerProgressbar=findViewById(R.id.registerProgressbar)
    }
}

Explanation

This code is for the registration screen (RegisterActivity) in an Android application using Firebase Authentication.

class RegisterActivity : AppCompatActivity() {
    private lateinit var editRegiEmail: EditText
    private lateinit var editRegiPassword: EditText
    private lateinit var regiBtn: Button
    private lateinit var redirectLogin: TextView
    private lateinit var registerProgressbar: ProgressBar
    private lateinit var auth: FirebaseAuth
    ...
}

Variable Declarations


editRegiEmail, editRegiPassword: EditText fields for user input of email and password.
regiBtn: Button for triggering the registration process.
redirectLogin: TextView for redirecting to the login screen.
registerProgressbar: ProgressBar to indicate registration progress.
auth: An instance of FirebaseAuth for Firebase Authentication.

onCreate() Method

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_register)
    auth = FirebaseAuth.getInstance()
    findId()
    createUser()
    redirectLoginPage()
}

Initialize the FirebaseAuth instance.
Call the findId() method to find and initialize the view elements.
Call the createUser() method to set up the registration logic.
Call the redirectLoginPage() method to handle redirection to the login screen.

findId() Method


Initialize the view elements by finding their respective IDs.

private fun findId() {
    editRegiEmail = findViewById(R.id.editTextEmail)
    editRegiPassword = findViewById(R.id.editTextPassword)
    regiBtn = findViewById(R.id.Regibutton)
    redirectLogin = findViewById(R.id.loginActivityRedirect)
    registerProgressbar = findViewById(R.id.registerProgressbar)
}

createUser() Method

private fun createUser() {
    regiBtn.setOnClickListener {
        val email = editRegiEmail.text.toString().trim()
        val password = editRegiPassword.text.toString().trim()
        if (email.isNotEmpty() && password.isNotEmpty()) {
            registerProgressbar.visibility = View.VISIBLE
            auth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this) { task ->
                registerProgressbar.visibility = View.INVISIBLE
                if (task.isSuccessful) {
                    Toast.makeText(this, "Registration successful", Toast.LENGTH_LONG).show()
                    val intent = Intent(this@RegisterActivity, LoginActivity::class.java)
                    startActivity(intent)
                    finish()
                } else {
                    Toast.makeText(
                        this,
                        "Registration failed: ${task.exception?.message}",
                        Toast.LENGTH_LONG
                    ).show()
                }
            }
        } else {
            Toast.makeText(this, "Please Enter Email and Password", Toast.LENGTH_LONG).show()
        }
    }
}

Set up the click listener for the registration button.
Retrieve user input for email and password.
Check if both fields are not empty.
If not empty, show a progress bar and attempt to create a user with Firebase Authentication.
Display success or failure messages accordingly.

redirectLoginPage() Method

Set up a click listener for the redirection TextView to go to the login screen.

private fun redirectLoginPage() {
    redirectLogin.setOnClickListener {
        startActivity(Intent(this, LoginActivity::class.java))
    }
}

Step 5: Login Screen

After completing the full registration page, the next step is to create a login page. For this, create a new empty activity named LoginActivity.

Next, create the UI for the login screen in the activity_login.xml layout file. This layout typically includes EditText fields for email and password and a Button for the login action.

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".LoginActivity">
    <EditText
        android:id="@+id/editTextLoginEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Enter Email"
        android:inputType="textEmailAddress" />
    <EditText
        android:id="@+id/editTextLoginPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/editTextLoginEmail"
        android:ems="10"
        android:hint="Enter Password"
        android:inputType="textPassword" />
    <Button
        android:id="@+id/loginbutton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/editTextLoginPassword"
        android:text="Login" />
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/loginProgressbar"
        android:visibility="gone"
        android:layout_centerInParent="true"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Forgot Password ?"
        android:textColor="@android:color/holo_blue_dark"
        android:layout_marginTop="10dp"
        android:id="@+id/textForgotPassword"
        android:layout_below="@id/loginbutton"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="5dp"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@id/textForgotPassword">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginStart="5dp"
            android:text="Don't have an Account? "/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Register Now."
            android:layout_marginTop="10dp"
            android:id="@+id/RegisterActivityRedirect"
            android:textColor="@android:color/holo_blue_dark"/>
    </LinearLayout>
</RelativeLayout>

Now, let’s add the backend code for the login process in the LoginActivity.kt

LoginActivity.kt

class LoginActivity : AppCompatActivity() {
    private lateinit var auth: FirebaseAuth
    private lateinit var loginEmail:EditText
    private lateinit var loginPassword:EditText
    private lateinit var loginButton:Button
    private lateinit var regiRedirect:TextView
    private lateinit var loginProgressbar:ProgressBar
    private lateinit var forgotPassword:TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        //create instance
        auth=FirebaseAuth.getInstance()
        findId()
        signingUser()
        redirectRegister()
        redirectForogtPassword()
    }
    private fun redirectForogtPassword() {
        forgotPassword.setOnClickListener {
            startActivity(Intent(this,ForgotPasswordActivity::class.java))
        }
    }
    private fun redirectRegister() {
        regiRedirect.setOnClickListener {
            startActivity(Intent(this,RegisterActivity::class.java))
        }
    }
    private fun signingUser() {
        loginButton.setOnClickListener{
            val email=loginEmail.text.toString().trim()
            val password=loginPassword.text.toString().trim()
            //check field is not mpty
            if (email.isNotEmpty() && password.isNotEmpty()){
                //display progressbar
                loginProgressbar.visibility= View.VISIBLE
                //signing with email and password
                auth.signInWithEmailAndPassword(email,password).addOnCompleteListener(this){task->
                    //hide the progressbar
                    loginProgressbar.visibility=View.INVISIBLE
                    if (task.isSuccessful){
                        //show login success message
                        Toast.makeText(this,"Login Successful",Toast.LENGTH_LONG).show()
                        //navigate welcome activity
                        startActivity(Intent(this,MainActivity::class.java))
                        finish()
                    }else{
                        //display the message if login failed
                        Toast.makeText(this,"Login Failed:${task.exception?.message}",Toast.LENGTH_LONG).show()
                    }
                }
            }else{
                //empty field validation
                Toast.makeText(this,"Please Enter Email and Password",Toast.LENGTH_LONG).show()
            }
        }
    }
    private fun findId() {
        loginEmail=findViewById(R.id.editTextLoginEmail)
        loginPassword=findViewById(R.id.editTextLoginPassword)
        loginButton=findViewById(R.id.loginbutton)
        regiRedirect=findViewById(R.id.RegisterActivityRedirect)
        loginProgressbar=findViewById(R.id.loginProgressbar)
        forgotPassword=findViewById(R.id.textForgotPassword)
    }
}

Explanation

This code is for the LoginActivity in an Android app using Firebase Authentication.

redirectForgotPassword Method

private fun redirectForgotPassword() {
    forgotPassword.setOnClickListener {
        startActivity(Intent(this, ForgotPasswordActivity::class.java))
    }
}

Sets up a click listener for the “Forgot Password?” text (forgotPassword).
Redirects the user to the ForgotPasswordActivity when the text is clicked.

redirectRegister Method

private fun redirectRegister() {
    regiRedirect.setOnClickListener {
        startActivity(Intent(this, RegisterActivity::class.java))
    }
}

Sets up a click listener for the “Register” text (regiRedirect).
Redirects the user to the RegisterActivity when the text is clicked.

signingUser Method

private fun signingUser() {
    loginButton.setOnClickListener {
        val email = loginEmail.text.toString().trim()
        val password = loginPassword.text.toString().trim()
        if (email.isNotEmpty() && password.isNotEmpty()) {
            loginProgressbar.visibility = View.VISIBLE
            auth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this) { task ->
                loginProgressbar.visibility = View.INVISIBLE
                if (task.isSuccessful) {
                    Toast.makeText(this, "Login Successful", Toast.LENGTH_LONG).show()
                    startActivity(Intent(this, MainActivity::class.java))
                    finish()
                } else {
                    Toast.makeText(this, "Login Failed: ${task.exception?.message}", Toast.LENGTH_LONG).show()
                }
            }
        } else {
            Toast.makeText(this, "Please Enter Email and Password", Toast.LENGTH_LONG).show()
        }
    }
}

Handles the login process when the login button (loginButton) is clicked.
Retrieves user input for email and password.
Validates that the fields are not empty.
Displays a progress bar during the login process.
Uses Firebase Authentication to sign in with the provided email and password.
Displays success or failure messages and navigates to the main activity on successful login.

Step 6: Logout Screen

After a user registers and logs in, the next step is to provide a way to log out. Typically, you would have a logout button in a welcome screen or another relevant screen. In this example, we assume that the logout functionality is part of the MainActivity.

Add a logout button in the activity_main.xml layout file.

activity_main.xml

<?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">
    <Button
        android:id="@+id/logoutbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="116dp"
        android:text="Logout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/textViewWelcomeMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        app:layout_constraintBottom_toTopOf="@+id/deletAccount"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/logoutbutton" />
    <TextView
        android:id="@+id/deletAccount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Delete Account"
        android:textColor="#F60505"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Now, in the MainActivity.kt file, add the code to handle the logout functionality

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var logoutbtn:Button
    private lateinit var auth: FirebaseAuth
    private lateinit var welcomeMessage:TextView
    private lateinit var deleteAccount:TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //create firebase instance
        auth=FirebaseAuth.getInstance()
        //find id
        logoutbtn=findViewById(R.id.logoutbutton)
       welcomeMessage=findViewById(R.id.textViewWelcomeMessage)
        deleteAccount=findViewById(R.id.deletAccount)
        logoutUser()
        displayWelcomeMessage()
        deleteAcc()
    }
    private fun deleteAcc() {
        deleteAccount.setOnClickListener {
            //prompt the user to enter their password
            val passwordPromtDialog=AlertDialog.Builder(this)
            val passwordEditText=EditText(this)
            passwordEditText.inputType=InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
            passwordPromtDialog.setView(passwordEditText)
            passwordPromtDialog.setTitle("Enter Password")
            passwordPromtDialog.setPositiveButton("oK"){_,_ ->
                val password=passwordEditText.text.toString().trim()
                //password empty validation
                if(password.isNotEmpty()){
                    val user=FirebaseAuth.getInstance().currentUser
                    val credential= EmailAuthProvider.getCredential(user?.email?:"",password)
                    user?.reauthenticate(credential)?.addOnCompleteListener(this){task->
                        if (task.isSuccessful){
                            //when user successful reauthenticate redirect register activity
                            deleteAccAndRedirect()
                        }else{
                            //show message if reauthenticate failed
                            Toast.makeText(this,"reAuthenticate failed:${task.exception?.message}",Toast.LENGTH_LONG).show()
                        }
                    }
                }else{
                    //handle empty field validation
                    Toast.makeText(this,"Please Enter your password",Toast.LENGTH_LONG).show()
                }
            }
            //set negative button
            passwordPromtDialog.setNegativeButton("Cancel",null)
            passwordPromtDialog.show()
        }
    }
    private fun deleteAccAndRedirect() {
        val user=FirebaseAuth.getInstance().currentUser
        user?.delete()?.addOnCompleteListener(this){task->
            if (task.isSuccessful){
                //account delete successful, redirect registration activity
                Toast.makeText(this,"Account Deleted Successfully",Toast.LENGTH_LONG).show()
                startActivity(Intent(this,RegisterActivity::class.java))
                finish()
            }else{
                //show message when deletion failure
                Toast.makeText(this,"Deletion Failure:${task.exception?.message}",Toast.LENGTH_LONG).show()
            }
        }
    }
    private fun displayWelcomeMessage() {
        val currentuser=auth.currentUser
        //check current user
        if (currentuser!=null){
            val userEmail=currentuser.email
            val welcome="Welcome ,${extractUserName(userEmail)}"
            welcomeMessage.text=welcome
        }
    }
    private fun extractUserName(userEmail: String?): String {
        return userEmail?.substringBefore("@")?:"User"
    }
    private fun logoutUser() {
        logoutbtn.setOnClickListener{
            FirebaseAuth.getInstance().signOut()
            //when user logout navigate login page
            startActivity(Intent(this,LoginActivity::class.java))
            finish()
        }
    }
}

Explanation

logoutUser Method

private fun logoutUser() {
    logoutbtn.setOnClickListener {
        FirebaseAuth.getInstance().signOut()
      
        startActivity(Intent(this, LoginActivity::class.java))
        finish()
    }
}

Sets up a click listener for the logout button (logoutbtn).
Signs out the user using Firebase Authentication.
Redirects the user to the login page.

displayWelcomeMessage Method

private fun displayWelcomeMessage() {
    val currentUser = auth.currentUser
    
    if (currentUser != null) {
        val userEmail = currentUser.email
        val welcome = "Welcome, ${extractUserName(userEmail)}"
        
        welcomeMessage.text = welcome
    }
}

Retrieves the current user using Firebase Authentication.
If a user is logged in, extracts the email and displays a welcome message.

extractUserName Method

private fun extractUserName(userEmail: String?): String {
    return userEmail?.substringBefore("@") ?: "User"
}

Extracts the username from the user’s email address.
Returns “User” if the email is null.

deleteAcc Method

    private fun deleteAcc() {
        deleteAccount.setOnClickListener {
            
            val passwordPromtDialog=AlertDialog.Builder(this)
            val passwordEditText=EditText(this)
            passwordEditText.inputType=InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
            passwordPromtDialog.setView(passwordEditText)
            passwordPromtDialog.setTitle("Enter Password")
            passwordPromtDialog.setPositiveButton("oK"){_,_ ->
                val password=passwordEditText.text.toString().trim()
                
                if(password.isNotEmpty()){
                    val user=FirebaseAuth.getInstance().currentUser
                    val credential= EmailAuthProvider.getCredential(user?.email?:"",password)
                    user?.reauthenticate(credential)?.addOnCompleteListener(this){task->
                        if (task.isSuccessful){
                            
                            deleteAccAndRedirect()
                        }else{
                            
                            Toast.makeText(this,"reAuthenticate failed:${task.exception?.message}",Toast.LENGTH_LONG).show()
                        }
                    }
                }else{
                    
                    Toast.makeText(this,"Please Enter your password",Toast.LENGTH_LONG).show()
                }
            }
            
            passwordPromtDialog.setNegativeButton("Cancel",null)
            passwordPromtDialog.show()
        }
    }

Sets up a click listener for the delete account TextView (deleteAccount).
Prompts the user to enter their password for account deletion.
Calls deleteAccAndRedirect() upon successful reauthentication.
Shows a failure message if reauthentication fails.
Calls deleteAccAndRedirect() upon successful account deletion.
Shows a failure message if account deletion fails.

deleteAccAndRedirect Method

    private fun deleteAccAndRedirect() {
        val user=FirebaseAuth.getInstance().currentUser
        user?.delete()?.addOnCompleteListener(this){task->
            if (task.isSuccessful){
                
                Toast.makeText(this,"Account Deleted Successfully",Toast.LENGTH_LONG).show()
                startActivity(Intent(this,RegisterActivity::class.java))
                finish()
            }else{
                
                Toast.makeText(this,"Deletion Failure:${task.exception?.message}",Toast.LENGTH_LONG).show()
            }
        }
    }

Retrieves the current user and deletes the account.
Redirects to the registration activity upon successful deletion.
Shows a failure message if deletion fails.

Step 7: Reset Password Screen

To enable users to reset their password, you need to create a ForgotPasswordActivity. This activity will be responsible for handling the “forgot password” functionality.

Create the layout for activity_forgot_password.xml

activity_forgot_password.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".ForgotPasswordActivity">
    <EditText
        android:id="@+id/editTextForgotPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Enter Email"
        android:inputType="textEmailAddress" />
    <Button
        android:id="@+id/resetButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Reset Password" />
</LinearLayout>

Create the ForgotPasswordActivity.kt file

ForgotPasswordActivity.kt

class ForgotPasswordActivity : AppCompatActivity() {
    private lateinit var auth: FirebaseAuth
    private lateinit var editforgotPassword:EditText
    private lateinit var resetBtn:Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_forgot_password)
        auth=FirebaseAuth.getInstance()
        //find id
        findId()
        sendPassword()
    }
    private fun sendPassword() {
        resetBtn.setOnClickListener{
            val email=editforgotPassword.text.toString().trim()
            if (email.isNotEmpty()){
                auth.sendPasswordResetEmail(email).addOnCompleteListener(this){task->
                //display alert dialog
                    val message:String=if(task.isSuccessful){
                        "Password reset email sent, please check your email"
                    }else{
                       "Failed to send reset password email:${task.exception?.message}"
                    }
                    //show Alert dialog with message
                    displayAlert(message,task.isSuccessful)
                }
            }else{
                //display empty field validation
                Toast.makeText(this,"Please Enter email address",Toast.LENGTH_LONG).show()
            }
        }
    }
    private fun displayAlert(message: String, successful: Boolean) {
        val alertDialog=AlertDialog.Builder(this)
        alertDialog.setTitle(if(successful)"success" else "Error")
        alertDialog.setMessage(message)
        alertDialog.setPositiveButton("Ok"){_,_->
        if (successful){
            //close the activity after sending reset email
            finish()
        }
        }
        alertDialog.show()
    }
    private fun findId() {
        editforgotPassword=findViewById(R.id.editTextForgotPassword)
        resetBtn=findViewById(R.id.resetButton)
    }
}

Explanation

sendPassword Method

private fun sendPassword() {
    resetBtn.setOnClickListener {
        val email = editforgotPassword.text.toString().trim()
        if (email.isNotEmpty()) {
            
            auth.sendPasswordResetEmail(email).addOnCompleteListener(this) { task ->
                
                val message: String = if (task.isSuccessful) {
                    "Password reset email sent, please check your email"
                } else {
                    "Failed to send reset password email: ${task.exception?.message}"
                }
                displayAlert(message, task.isSuccessful)
            }
        } else {
            
            Toast.makeText(this, "Please Enter email address", Toast.LENGTH_LONG).show()
        }
    }
}

Sets up a click listener for the reset button (resetBtn).
Retrieves the email entered by the user.
Sends a password reset email using Firebase Authentication.
Displays an alert dialog with the result message (success or error).
Calls displayAlert() to handle the display of the alert dialog.

displayAlert Method

private fun displayAlert(message: String, successful: Boolean) {
    val alertDialog = AlertDialog.Builder(this)
    alertDialog.setTitle(if (successful) "Success" else "Error")
    alertDialog.setMessage(message)
    alertDialog.setPositiveButton("Ok") { _, _ ->
        if (successful) {
            
            finish()
        }
    }
    alertDialog.show()
}

Sets up an alert dialog with a title and a message based on the success of the password reset.
Adds a positive button with the label “Ok” that closes the activity after sending the reset email, if successful.
Shows the alert dialog.

Hurray! We have successfully created user registration, login, logout, forgot password, and account deletion functionalities using Firebase Authentication.

Now, it’s time to test your app on an Android emulator or a real Android device, whichever you prefer. Verify that all the functionalities are working as expected, and also test if the forgot password feature sends emails correctly.

user registration screen
user registration screen

user login screen
user login screen

reset password screen
reset password screen

logout button and welcome screen
logout button and welcome screen

password reset authentication
password reset authentication

We’ve implemented a straightforward user login system using Android Studio and Firebase Authentication.

If you have any doubts, feel free to send a message or provide feedback.

Leave a Reply