Kotlin Firebase Authentication – How to Sign Up, Sign In, Sign Out, Verify Email | Android

Firebase Authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your app. In this tutorial, we’re gonna build a simple register/login Android App using Firebase Email & Password authentication with Kotlin language.

More Practice:
Kotlin Firebase Authentication – Send Reset Password Email / Forgot Password | Android
Kotlin Firebase Authentication – Google Sign In | Android

I. Way to do

1. Add Firebase to Android Project

1.1 Step by step

– Create new Android App including Kotlin support.
– From menu bar, Tool -> Firebase:
kotlin-firebase-auth-setup-tool

– Assistant window will be shown. Choose Authentication, then click on Email and password authentication:
kotlin-firebase-auth-setup-0

– At the step 1, click on Connect to Firebase:
kotlin-firebase-auth-setup-1

– In new Window, choose Create new Project and fill in the name of Firebase Project:
kotlin-firebase-auth-setup-2

– Click on Connect to Firebase, the Browser will show new Firebase Project that has just been created:
kotlin-firebase-auth-setup-5

– Come back to Android Studio, at the step 2, click on Add Firebase Authentication to your app:
kotlin-firebase-auth-setup-3

– You will see a new window that shows the code will be add to build.gradle files. Click on Accept Changes:
kotlin-firebase-auth-setup-4

– Now view your Project under Project type, you can see google-services.json file:
kotlin-firebase-auth-setup-json

1.2 Check dependencies

Open Gradle file to check what happens, we can see that some code has been added:
build.gradle (project-level):


buildscript {
    // ...
    dependencies {
        // ...
        classpath 'com.google.gms:google-services:3.1.0'
    }
}

build.gradle (App-level):


dependencies {
    // ...
    implementation 'com.google.firebase:firebase-auth:11.0.4'
}

apply plugin: 'com.google.gms.google-services'

2. Enable Firebase Auth

Go to Your Firebase Project Console -> Authentication -> SIGN-IN METHOD -> Enable Email/Password:
kotlin-firebase-auth-setup-6

3. Work with FirebaseAuth object

3.1 Initialize the FirebaseAuth instance

In the Activity onCreate():


private var mAuth: FirebaseAuth? = null

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    mAuth = FirebaseAuth.getInstance()
}

3.2 Check if the user is currently signed in

In Activity onStart():


override fun onStart() {
    // ...
    val currentUser = mAuth!!.currentUser
    updateUI(currentUser)
}

3.3 Sign up a new user

Creates new user with the createUserWithEmailAndPassword() method:


mAuth!!.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in: success
                // update UI for current User
                val user = mAuth!!.currentUser
                updateUI(user)
            } else {
                // Sign in: fail
                updateUI(null)
            }
        }

3.4 Sign in an existing user

Login with signInWithEmailAndPassword() method:


mAuth!!.signInWithEmailAndPassword(email, password)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in: success
                // update UI for current User
                val user = mAuth!!.getCurrentUser()
                updateUI(user)
            } else {
                // Sign in: fail
                Log.e(TAG, "signIn: Fail!", task.exception)
                updateUI(null)
            }

            // ...
        }

3.5 Access user information

Get Information of a user from FirebaseUser object:


val user = FirebaseAuth.getInstance().currentUser

if (user != null) {
    // Name, email address, and profile photo Url
    val name = user.displayName
    val email = user.email
    val photoUrl = user.photoUrl

    // Check if user's email is verified
    val emailVerified = user.isEmailVerified

    // The user's ID, unique to the Firebase project.
    val uid = user.uid
}

3.6 Sign out current user

Log out with signOut() method:


mAuth!!.signOut()

3.7 Send Email Verification

We can send an email to verify User with sendEmailVerification() method. If the task is successful, the email was sent.


val user = mAuth!!.currentUser
user!!.sendEmailVerification()
        .addOnCompleteListener(this) { task ->
            // Re-enable Verify Email button
            findViewById(R.id.btn_verify_email).isEnabled = true
            if (task.isSuccessful) {
                Log.e(TAG, "Verification email sent to " + user.email!!)
            } else {
                Log.e(TAG, "sendEmailVerification failed!", task.exception)
            }
        }

This email template is shown on the Email Templates tab in the Authentication section of the Firebase console:
firebaseauth-email-verification-template

II. Practice

1. Goal

We will build an Android App that can:
– create Account, sign in/sign out, send email verification.
– display current status/user information with verified email status.

kotlin-firebase-auth-goal

2. Technology

– Gradle 3.0.1
– Android Studio 3.x
– Firebase Android SDK 11.x

3. Project Structure

kotlin-firebase-auth-structure

4. Step by step

4.1 Create Android Project & Add Firebase Auth

– Generate new Android Project with package com.javasampleapproach.kotlin.firebase.auth.
– Follow these steps to add Firebase to Android Project.

4.2 Enabling Firebase Auth

Go to Your Firebase Project Console -> Authentication -> SIGN-IN METHOD -> Enable Email/Password:
kotlin-firebase-auth-setup-6

4.3 Activity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="3">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="grokonez.com"
            android:textSize="28sp" />

        <TextView
            android:id="@+id/tvStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="4dp"
            android:text="Signed Out"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/tvDetail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="4dp"
            android:textSize="14sp"
            tools:text="Firebase User ID: 123456789abc" />

    </LinearLayout>


    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#E0E0E0"
        android:gravity="center_vertical">

        <LinearLayout
            android:id="@+id/email_password_fields"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="16dp"
            android:paddingRight="16dp">

            <EditText
                android:id="@+id/edtEmail"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="Email"
                android:inputType="textEmailAddress" />

            <EditText
                android:id="@+id/edtPassword"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="Password"
                android:inputType="textPassword" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/email_password_buttons"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/email_password_fields"
            android:orientation="horizontal"
            android:paddingLeft="16dp"
            android:paddingRight="16dp">

            <Button
                android:id="@+id/btn_email_sign_in"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_weight="1"
                android:text="Sign In" />

            <Button
                android:id="@+id/btn_email_create_account"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_weight="1"
                android:text="Create Account" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/layout_signed_in_buttons"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:orientation="horizontal"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:visibility="gone"
            android:weightSum="2.0">

            <Button
                android:id="@+id/btn_sign_out"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_weight="1.0"
                android:text="Sign Out" />

            <Button
                android:id="@+id/btn_verify_email"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_weight="1.0"
                android:text="Verify Email" />

        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

package com.javasampleapproach.kotlin.firebase.auth

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_login.*
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import android.widget.Toast
import android.util.Log
import android.text.TextUtils

class LoginActivity : AppCompatActivity(), View.OnClickListener {

    private val TAG = "FirebaseEmailPassword"

    private var mAuth: FirebaseAuth? = null

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

        btn_email_sign_in.setOnClickListener(this)
        btn_email_create_account.setOnClickListener(this)
        btn_sign_out.setOnClickListener(this)
        btn_verify_email.setOnClickListener(this)

        mAuth = FirebaseAuth.getInstance()
    }

    override fun onStart() {
        super.onStart()

        val currentUser = mAuth!!.currentUser
        updateUI(currentUser)
    }

    override fun onClick(view: View?) {
        val i = view!!.id

        if (i == R.id.btn_email_create_account) {
            createAccount(edtEmail.text.toString(), edtPassword.text.toString())
        } else if (i == R.id.btn_email_sign_in) {
            signIn(edtEmail.text.toString(), edtPassword.text.toString())
        } else if (i == R.id.btn_sign_out) {
            signOut()
        } else if (i == R.id.btn_verify_email) {
            sendEmailVerification()
        }
    }

    private fun createAccount(email: String, password: String) {
        Log.e(TAG, "createAccount:" + email)
        if (!validateForm(email, password)) {
            return
        }

        mAuth!!.createUserWithEmailAndPassword(email, password)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Log.e(TAG, "createAccount: Success!")

                        // update UI with the signed-in user's information
                        val user = mAuth!!.currentUser
                        updateUI(user)
                    } else {
                        Log.e(TAG, "createAccount: Fail!", task.exception)
                        Toast.makeText(applicationContext, "Authentication failed!", Toast.LENGTH_SHORT).show()
                        updateUI(null)
                    }
                }
    }

    private fun signIn(email: String, password: String) {
        Log.e(TAG, "signIn:" + email)
        if (!validateForm(email, password)) {
            return
        }

        mAuth!!.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        Log.e(TAG, "signIn: Success!")

                        // update UI with the signed-in user's information
                        val user = mAuth!!.getCurrentUser()
                        updateUI(user)
                    } else {
                        Log.e(TAG, "signIn: Fail!", task.exception)
                        Toast.makeText(applicationContext, "Authentication failed!", Toast.LENGTH_SHORT).show()
                        updateUI(null)
                    }

                    if (!task.isSuccessful) {
                        tvStatus.text = "Authentication failed!"
                    }
                }
    }

    private fun signOut() {
        mAuth!!.signOut()
        updateUI(null)
    }

    private fun sendEmailVerification() {
        // Disable Verify Email button
        findViewById(R.id.btn_verify_email).isEnabled = false

        val user = mAuth!!.currentUser
        user!!.sendEmailVerification()
                .addOnCompleteListener(this) { task ->
                    // Re-enable Verify Email button
                    findViewById(R.id.btn_verify_email).isEnabled = true

                    if (task.isSuccessful) {
                        Toast.makeText(applicationContext, "Verification email sent to " + user.email!!, Toast.LENGTH_SHORT).show()
                    } else {
                        Log.e(TAG, "sendEmailVerification failed!", task.exception)
                        Toast.makeText(applicationContext, "Failed to send verification email.", Toast.LENGTH_SHORT).show()
                    }
                }
    }

    private fun validateForm(email: String, password: String): Boolean {

        if (TextUtils.isEmpty(email)) {
            Toast.makeText(applicationContext, "Enter email address!", Toast.LENGTH_SHORT).show()
            return false
        }

        if (TextUtils.isEmpty(password)) {
            Toast.makeText(applicationContext, "Enter password!", Toast.LENGTH_SHORT).show()
            return false
        }

        if (password.length < 6) {
            Toast.makeText(applicationContext, "Password too short, enter minimum 6 characters!", Toast.LENGTH_SHORT).show()
            return false
        }

        return true
    }

    private fun updateUI(user: FirebaseUser?) {

        if (user != null) {
            tvStatus.text = "User Email: " + user.email + "(verified: " + user.isEmailVerified + ")"
            tvDetail.text = "Firebase User ID: " + user.uid

            email_password_buttons.visibility = View.GONE
            email_password_fields.visibility = View.GONE
            layout_signed_in_buttons.visibility = View.VISIBLE

            btn_verify_email.isEnabled = !user.isEmailVerified
        } else {
            tvStatus.text = "Signed Out"
            tvDetail.text = null

            email_password_buttons.visibility = View.VISIBLE
            email_password_fields.visibility = View.VISIBLE
            layout_signed_in_buttons.visibility = View.GONE
        }
    }
}

4.4 Set main launcher activity

Open AndroidManifest.xml and make the LoginActivity.java as launcher activity (set it as the first screen).

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javasampleapproach.firebaseauth">

    <application ...>
        <activity android:name=".LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4.5 Run & Check result

- Use Android Studio, build and Run your Android App.

- Fill in Email & Password field, then click CREATE ACCOUNT button:
kotlin-firebase-auth-test-create-account

- Open Firebase Project Console to check user:
kotlin-firebase-auth-test-create-account-ok-console

- Click VERIFY EMAIL button:
kotlin-firebase-auth-test-create-account-verify-email

Then check email:
kotlin-firebase-auth-test-create-account-verify-email-click

- Click link in the email to verify, the browser shows:
kotlin-firebase-auth-test-create-account-verify-email-click-ok

- Go back to Android App, sign out, then sign in, the account is verified now:
kotlin-firebase-auth-test-create-account-verify-ok

III. Source code

Kotin-FirebaseAuth-email-password



By grokonez | December 14, 2017.

Last updated on May 22, 2021.



Related Posts


7 thoughts on “Kotlin Firebase Authentication – How to Sign Up, Sign In, Sign Out, Verify Email | Android”

Got Something To Say:

Your email address will not be published. Required fields are marked *

*