Hire the author: Moses N

Image Source https://blog.scalefusion.com/wp-content/uploads/2FA-fb@2x-768×497.png

Here is the GitHub – android-2step authentication-Firebase link for this project.

Introduction

Firebase authentication adds one layer of security while Android two-step authentication henceforth will add an extra layer of security to your application. In this blog, we are going to follow a step by step tutorial on how to create an android two-step authentication signup system using Firebase and as a result, it will add a second layer of authentication”two-factor authentication (2FA)”.


Firebase is Google’s mobile platform that helps you quickly develop high-quality apps because it provides a real-time database and backend as a service and in the two-step authentication signup system we will use Firebase services such as Firebase real-time database and Firebase authentication.

What motivated me in doing this project “android two-step authentication signup system using Firebase” is because security is the key thing in each and every application more so allowing a two-step authentication will add another layer of security before a user manages to access the application. In Addition, Android technology is on the rise such that each and every person finds it easy to own, hence most of the system is shifting to having an android application, and applying this two-step authentication for users will increase security.

How to Get Started

This project is a starting point for Firebase application development and below are a few resources to get you prepared before starting this project:

Online documentation is essential and it offers tutorials, samples, guidance on mobile development, and a full API reference. However, You can check on the Firebase documentation.

Photo Preview

Glossary

  • Firebase – is a Backend-as-a-Service (Baas) because It provides developers with a variety of tools. Also, services to help them develop quality apps, grow their user base, and earn a profit.
  • Authentication – Authentication is the process of determining whether someone or something is, in fact, who or what it declares itself to be. For instance, Authentication technology provides access control for systems. Checking to see if a user’s credentials match the credentials in a database of authorized users or in a data authentication server
  • Verification – is the process of checking user details are correct. For instance, the password field and confirming the password is correct.
  • A Reference – represents a specific location in your Database. It can be used for reading or writing data to that Database location.
  • Intent – In android, an intent is a software mechanism that allows users to coordinate the functions of different activities to achieve a task. As a result, It allows one to navigate within activities easily.

Steps:

Step 1: Connecting android studio project to Firebase

Firstly, let’s connect the android studio to Firebase and we will be using user email. We will then connect our project to the Firebase. Since we will be using Firebase services such as Firebase Authentication, Firebase real-time database, and Firebase storage.

To connect with your email.

  1. On the top left of the menu, toolbar click on it. Click “add account”.
  2. You will be directed to log in to your email.
  3. Enter the email and password.
  4. Click on Firebase console.


Once connected your project should have your email as shown below in the image.

How to create an android two step authentication signup system using Firebase

To connect to Firebase services.

  1. On the android studio, click on the Tools menu.
  2. Then click on Firebase.
  3. A menu containing Firebase services will appear on your right.
  4. Click on Firebase Authentication. Connect to Firebase.
  5. Enter the name of your project and click on email and password to add Firebase authentication dependencies.
  6. Click on the real-time database, then on save and retrieve data.
  7. Lastly, click on storage “upload and download a file with cloud storage”

As a result, all Firebase dependencies are added to your project.

How to create an android two step authentication signup system using Firebase
//firebase dependencies
implementation 'com.google.firebase:firebase-auth:16.0.5'
implementation 'com.google.firebase:firebase-storage:16.0.4'
implementation 'com.google.firebase:firebase-database:16.0.4'
//firebase dependencies

The first is used for Firebase authentication and more so the version will depend on the version android studio you are using. Moreover, you can use a higher version or stick to this.

To allow a user to sign in with email and password.

  1. Go to Firebase console.
  2. Choose your application
  3. Click on authentication on the left side menu.
  4. Sign-in method.
  5. Enable email/password.
How to create an android two step authentication signup system using Firebase

By default, your database rules require Firebase Authentication while Grant full read and write permissions only to authenticated users. The default rules ensure your database isn’t accessible by just anyone. Once you’re set-up, you can customize your rules to your needs. In this case, in order to write and read from Firebase. We will allow full user permission.

  • On the Firebase console right menu.
  • Click on the database.
  • Then User and permissions.
  • Write this code shown below to allow permissions.
// These rules  allow anyone read or write access to your database
{
  "rules": {
    ".read": true,
    ".write": true
  }
}

build.gradle(Module: app) project dependencies.

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
//firebase dependencies
implementation 'com.google.firebase:firebase-auth:16.0.5'
implementation 'com.google.firebase:firebase-storage:16.0.4'
implementation 'com.google.firebase:firebase-database:16.0.4'
//firebase dependencies
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//User design dependencies
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'de.hdodenhof:circleimageview:3.0.2'
//User design dependencies
}
view raw build.gradle hosted with ❤ by GitHub

We are going to add some dependencies purposely for designing a good user interface.

implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'de.hdodenhof:circleimageview:3.0.2'

Step 2: Designing the home Activity

This will be the final page. “Home”. Because we will land here after the two-step authentication. In order to complete our stages, we will first design this page so that after completing the second step of authentication we will land here.

<?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=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_marginTop="50dp"
android:background="@drawable/button"
android:layout_centerInParent="true"
app:cardElevation="5dp"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_marginLeft="8dp"
android:text="Two Step Authentication"
android:textAlignment="center"
android:textColor="@color/colorRed"
android:textSize="24sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/logo"
android:layout_marginLeft="8dp"
android:layout_marginRight="24dp"
android:layout_marginTop="-20dp"
android:background="@color/colorPrimaryDark"
android:layout_marginStart="8dp"
android:layout_marginEnd="24dp" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/logo"
android:elevation="5dp"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="60dp"
android:layout_toEndOf="@+id/title"
android:layout_toRightOf="@+id/title"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
<TextView
android:id="@+id/welcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Thank you for Completing the two step authentication with Firebase, Happy Coding"
android:textColor="@color/deepBlue"
android:textAlignment="center"
android:layout_gravity="center"
android:textSize="20sp"
android:layout_margin="20dp"
android:textStyle="italic"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

Step 3: Designing First step Authentication

It will involve registering user information via email and password. Create a step_one_authentication activity to hold the user registration information.

It contains three edit texts, three text views, and one button, and most importantly these fields, “email, password and confirm password”.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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=".Register">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="2dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_marginLeft="8dp"
android:text="Two Step Authentication"
android:textAlignment="center"
android:textColor="@color/colorRed"
android:textSize="24sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/logo"
android:layout_marginLeft="8dp"
android:layout_marginRight="24dp"
android:layout_marginTop="-20dp"
android:background="@color/colorPrimaryDark"
android:layout_marginStart="8dp"
android:layout_marginEnd="24dp" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/logo"
android:elevation="5dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="60dp"
android:layout_toEndOf="@+id/title"
android:layout_toRightOf="@+id/title"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
<TextView
android:id="@+id/personalInformation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Step one Authentication"
android:textColor="@color/colorRed"
android:textAlignment="center"
android:layout_gravity="center"
android:textSize="20sp"
android:textStyle="italic"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email Address"
android:textSize="18sp"
android:layout_marginLeft="10dp"
/>
<EditText
android:id="@+id/editemail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your email adress"
android:background="@drawable/input_field"
android:padding="15dp"
android:drawableLeft="@drawable/ic_email"
android:inputType="textEmailAddress"
android:layout_margin="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:textSize="18sp"
android:layout_marginLeft="10dp"
/>
<EditText
android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword"
android:background="@drawable/input_field"
android:drawableLeft="@drawable/ic_lock"
android:padding="15dp"
android:layout_margin="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Confirm Password"
android:textSize="18sp"
android:layout_marginLeft="10dp"
/>
<EditText
android:id="@+id/editPasswordConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:background="@drawable/input_field"
android:drawableLeft="@drawable/ic_lock"
android:padding="15dp"
android:inputType="textPassword"
android:layout_margin="10dp"/>
<Button
android:id="@+id/register_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:background="@drawable/input"
android:padding="10dp"
android:textSize="18dp"
android:textAllCaps="false"
android:layout_marginTop="24dp"
android:layout_gravity="center"
android:textColor="@android:color/white"
android:text="Register"
/>
</LinearLayout>

On the stepOneAuthentication let’s allow the user to register via email and password. We will also make sure that the user does not leave any of the fields blank and also confirm that the password and password confirm matches.

if (TextUtils.isEmpty(Email)){
                Toast.makeText(Register.this, "Please enter your email...", Toast.LENGTH_SHORT).show();
            }
else if(TextUtils.isEmpty(Password)){
                Toast.makeText(Register.this, "Please enter your password...", Toast.LENGTH_SHORT).show();
            }
else if (TextUtils.isEmpty(PasswordConfirm)){
                Toast.makeText(Register.this, "PLease confirm your password...", Toast.LENGTH_SHORT).show();
            }
else if(!Password.equals(PasswordConfirm)){
                Toast.makeText(Register.this, "Password do no match...", Toast.LENGTH_SHORT).show();

            }

We will use a Firebase method as shown below to allow registering through email and password and if the task is successful, the user is directed to second step authentication. If not an error message pops up.

 mAuth.createUserWithEmailAndPassword(Email,Password)
  .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
 @Override
 public void onComplete(@NonNull Task<AuthResult> task) {
 //checking if the task is sucessful
if(task.isSuccessful()){                                       SenduserToSTepTwoAuthentication();                                     Toast.makeText(Register.this, "You have passed the first  step authentication...", Toast.LENGTH_SHORT).show();
 loadingBar.dismiss();
  }
else{
  String message = task.getException().getMessage();                                   Toast.makeText(Register.this, "error occured" + message, Toast.LENGTH_SHORT).show();                                   }
loadingBar.dismiss();
 }
 });


package com.example.twostepauthentication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public class Register extends AppCompatActivity {
private EditText edit_email,edit_password,edit_confirmPassword;
private Button register;
private FirebaseAuth mAuth;
//adding a progress dialog box
private ProgressDialog loadingBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
mAuth = FirebaseAuth.getInstance();
edit_email = findViewById(R.id.editemail);
edit_password =findViewById(R.id.editPassword);
edit_confirmPassword = findViewById(R.id.editPasswordConfirm);
loadingBar = new ProgressDialog(this);
register = findViewById(R.id.register_button);
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
//creating account for users
CreateNewAccount();
}
});
}
@Override
protected void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser !=null)
{
SendUserToMainActivity();
}
}
private void SendUserToMainActivity()
{
Intent mainIntent = new Intent(Register.this,MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
finish();
}
private void CreateNewAccount()
{
//getting the values from the input fields
String Email = edit_email.getText().toString();
String Password = edit_password.getText().toString();
String PasswordConfirm = edit_confirmPassword.getText().toString();
//adding validation if user left any of the fields empty
if (TextUtils.isEmpty(Email)){
Toast.makeText(Register.this, "Please enter your email...", Toast.LENGTH_SHORT).show();
}
else if(TextUtils.isEmpty(Password)){
Toast.makeText(Register.this, "Please enter your password...", Toast.LENGTH_SHORT).show();
}
else if (TextUtils.isEmpty(PasswordConfirm)){
Toast.makeText(Register.this, "PLease confirm your password...", Toast.LENGTH_SHORT).show();
}
else if(!Password.equals(PasswordConfirm)){
Toast.makeText(Register.this, "Password do no match...", Toast.LENGTH_SHORT).show();
}
else{
//progress bar
loadingBar.setTitle("Creating new Account");
loadingBar.setMessage("please wait...");
loadingBar.show();
loadingBar.setCanceledOnTouchOutside(true);
//creating account for user
mAuth.createUserWithEmailAndPassword(Email,Password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
//checking if the task is sucessful
if (task.isSuccessful()){
SenduserToSTepTwoAuthentication();
Toast.makeText(Register.this, "You have passed the first step authentication...", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
else{
String message = task.getException().getMessage();
Toast.makeText(Register.this, "error occured" + message, Toast.LENGTH_SHORT).show(); }
loadingBar.dismiss();
}
});
}
}
private void SenduserToSTepTwoAuthentication()
{
Intent setupIntent = new Intent(Register.this,StepTwoAuthentication.class);
setupIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(setupIntent);
finish();
}
{
}
}

Step 4: Designing Login Activity

Only users who have passed the first step authentication can log in to the system. For instance, if you enter your email and password, these fields are authenticated. If they exist in the Firebase authentication real-time database, the user is directed to the second step authentication.

How to create an android two step authentication signup system using Firebase

Login user interface code looks like:

<?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=".Login">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_marginLeft="8dp"
android:text="Two Step Authentication"
android:textAlignment="center"
android:textColor="@color/colorRed"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="8dp"
android:text="Login"
android:typeface="serif"
android:padding="3dp"
android:layout_above="@+id/view"
android:layout_marginBottom="20dp"
android:textAlignment="center"
android:textColor="@color/colorPrimaryDark"
android:textSize="24sp"
android:textStyle="bold" />
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/logo"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="-20dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:background="@color/colorPrimaryDark" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/logo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="60dp"
android:layout_toEndOf="@+id/title"
android:layout_toRightOf="@+id/title"
android:elevation="5dp"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
<EditText
android:id="@+id/editemail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:background="@drawable/input_field"
android:ems="10"
android:inputType="textEmailAddress"
android:hint="Email"
android:drawableLeft="@drawable/ic_email"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/relativeLayout" />
<EditText
android:id="@+id/editpassword"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:ems="10"
android:padding="16dp"
android:background="@drawable/input_field"
android:inputType="textPassword"
android:hint="Password"
android:drawableLeft="@drawable/ic_lock"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editemail" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:textSize="16sp"
android:text="Remember me"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editpassword" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:text="Forgot Password?"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/checkBox"
app:layout_constraintTop_toBottomOf="@+id/editpassword" />
<Button
android:id="@+id/loginbutton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:text="Login"
android:textColor="@android:color/white"
android:textAllCaps="false"
android:background="@drawable/input"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<TextView
android:id="@+id/textView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="24dp"
android:padding="10dp"
android:text="Don't have an Account?"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@color/colorPrimaryDark"
android:textSize="18dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginbutton" />
<TextView
android:id="@+id/RegisterText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="168dp"
android:onClick="RegisteActivity"
android:text="Register"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@color/colorRed"
android:textSize="18dp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
FirebaseUser currentUser = mAuth.getCurrentUser();

Gets the current User. For instance, the user who has just has registered

currentUser !=null

Ensures that the user is not equal to null. If a user is null. He is prompted to register.

package com.example.twostepauthentication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public class Login extends AppCompatActivity {
private EditText edit_email,edit_password;
private Button login_Button;
private FirebaseAuth mAuth;
private ProgressDialog loadingBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mAuth = FirebaseAuth.getInstance();
edit_email =findViewById(R.id.editemail);
edit_password = findViewById(R.id.editpassword);
login_Button = findViewById(R.id.loginbutton);
//logging the user in
loadingBar =new ProgressDialog(this);
login_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
AllowUserToLogin();
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser !=null)
{
SendUserToMainActivity();
}
}
});
}
@Override
protected void onStart() {
super.onStart();
}
private void AllowUserToLogin()
{
String email = edit_email.getText().toString().trim();
String password = edit_password.getText().toString().trim();
if (TextUtils.isEmpty(email))
{
Toast.makeText(this, "Please write your email...", Toast.LENGTH_SHORT).show();
}
else if(TextUtils.isEmpty(password)){
Toast.makeText(this, "Please write your password", Toast.LENGTH_SHORT).show();
}
else
{
//progress bar
loadingBar.setTitle("Log In");
loadingBar.setMessage("please wait...");
loadingBar.show();
loadingBar.setCanceledOnTouchOutside(true);
mAuth.signInWithEmailAndPassword(email,password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
SendUserToMainActivity();
Toast.makeText(Login.this, "You are logged in successful", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
else
{
String message = task.getException().getMessage();
Toast.makeText(Login.this, "error occurred" +message, Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
}
}
private void SendUserToMainActivity()
{
Intent mainIntent = new Intent(Login.this,MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
finish();
}
//if user has no account will be directed to register
public void RegisteActivity(View view)
{
Intent registerIntent = new Intent(Login.this,Register.class);
startActivity(registerIntent);
}
}
view raw Login.java hosted with ❤ by GitHub

Step 5: Step-two Authentication

After successful verification of email and password, a user is directed to step-two authentication. This step will involve providing more information about the user before heading to the home activity of the system. For instance, in our case will do this by allowing the user to provide his/her first name, other names, and his/her phone number.

We will use the shown below method to store data in the Firebase database. It holds two variables. The first one is the name of the field such as the “the heading”. Second is the value stored.

HashMap userMap = new HashMap();
userMap.put("FirstName",firstname);
userMap.put("OtherName",othernames);
userMap.put("Phone",phonenumber);


<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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=".StepTwoAuthentication">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_centerInParent="true"
app:cardElevation="5dp"
android:background="@drawable/button"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="2dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_marginLeft="8dp"
android:text="Two Step Authentication"
android:textAlignment="center"
android:textColor="@color/colorRed"
android:textSize="24sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/logo"
android:layout_marginLeft="8dp"
android:layout_marginRight="24dp"
android:layout_marginTop="-20dp"
android:background="@color/colorPrimaryDark"
android:layout_marginStart="8dp"
android:layout_marginEnd="24dp" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/logo"
android:elevation="5dp"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="60dp"
android:layout_toEndOf="@+id/title"
android:layout_toRightOf="@+id/title"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
<TextView
android:id="@+id/personalInformation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Step two Setup Information"
android:textColor="@color/colorRed"
android:textAlignment="center"
android:layout_gravity="center"
android:textSize="20sp"
android:textStyle="italic"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First Name"
android:textSize="18sp"
android:layout_marginLeft="10dp"
/>
<EditText
android:id="@+id/editfirstname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your name"
android:background="@drawable/input_field"
android:padding="15dp"
android:inputType="textPersonName"
android:layout_margin="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Other names"
android:textSize="18sp"
android:layout_marginLeft="10dp"
/>
<EditText
android:id="@+id/editothernames"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your other names"
android:inputType="textPersonName"
android:background="@drawable/input_field"
android:padding="15dp"
android:layout_margin="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone Number"
android:textSize="18sp"
android:layout_marginLeft="10dp"
/>
<EditText
android:id="@+id/editphonenumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="+254"
android:background="@drawable/input_field"
android:padding="15dp"
android:inputType="number"
android:layout_margin="10dp"/>
<Button
android:id="@+id/save_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:background="@drawable/input"
android:padding="10dp"
android:textSize="18dp"
android:textAllCaps="false"
android:layout_marginTop="24dp"
android:layout_gravity="center"
android:textColor="@android:color/white"
android:text="Save"
/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</ScrollView>

package com.example.twostepauthentication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.HashMap;
public class StepTwoAuthentication extends AppCompatActivity {
private EditText edit_firstname, edit_othernames,edit_phonenumber;
private Button save;
private FirebaseAuth mAuth;
private DatabaseReference userRef;
private ProgressDialog loadingBar;
String currentUserID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_step_two_authentication);
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
userRef = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUserID);
edit_firstname = findViewById(R.id.editfirstname);
edit_othernames = findViewById(R.id.editothernames);
edit_phonenumber = findViewById(R.id.editphonenumber);
save = findViewById(R.id.save_button);
loadingBar = new ProgressDialog(this);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SaveInformation();
}
});
}
private void SaveInformation()
{
String firstname = edit_firstname.getText().toString().trim();
String othernames = edit_othernames.getText().toString().trim();
String phonenumber = edit_phonenumber.getText().toString().trim();
if (TextUtils.isEmpty(firstname))
{
Toast.makeText(this, "plese write your first name", Toast.LENGTH_SHORT).show();
}
if (TextUtils.isEmpty(othernames))
{
Toast.makeText(this, "plese write your other name", Toast.LENGTH_SHORT).show();
}
if (TextUtils.isEmpty(phonenumber))
{
Toast.makeText(this, "plese write your phone number", Toast.LENGTH_SHORT).show();
}
else {
loadingBar.setTitle("Saving Information");
loadingBar.setMessage("please wait...");
loadingBar.show();
loadingBar.setCanceledOnTouchOutside(true);
//saving information on the databse
HashMap userMap = new HashMap();
userMap.put("FirstName",firstname);
userMap.put("OtherName",othernames);
userMap.put("Phone",phonenumber);
//store
userRef.updateChildren(userMap).addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()){
SendUserToMainActivity();
Toast.makeText(StepTwoAuthentication.this, "Your account is created successfully", Toast.LENGTH_LONG).show();
loadingBar.dismiss();
}
else {
String message = task.getException().getMessage();
Toast.makeText(StepTwoAuthentication.this, "error corred" + message, Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
}
}
private void SendUserToMainActivity()
{
Intent mainIntent = new Intent(StepTwoAuthentication.this,MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
finish();
}
}

Step 6: Home Activity Authentication

Here we have to check the User Existence in the Firebase database. For instance, if the user provides both email and password in the first step authentication. Additional information in the second step authentication, he accesses the home activity. Otherwise, access is denied.

To check user existence in the Firebase database. We are going to use “DataSnapshot”. DataSnapshot is used to fetch data from the node whenever a listener event is triggered by the database. In this case, we will use it to check if the user exists in the database.

Since the first method of authentication, email, and password are not stored in the Firebase database. Therefore, we get the current user Id and use DataSnapshot to check if he has registered.

If a user exists in the Firebase database, that is he has already registered via email and password and has provided step two authentication information. He is directed to the home page else he is directed to step two authentication.

private void CheckUserExistence()
{
//get the user id
final String currentUserId =mAuth.getCurrentUser().getUid();
 userRef.addValueEventListener(new ValueEventListener() {
  @Override
 public void onDataChange(@NonNull DataSnapshot dataSnapshot)
 {
  if (!dataSnapshot.hasChild(currentUserId)){
  //user is authenticated but but his record is not present in real time firebase database
   SendUserToStepTwoAuthentication();
   }
  }
 @Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
 });


package com.example.twostepauthentication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Intent;
import android.os.Bundle;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class MainActivity extends AppCompatActivity {
//firebase auth to check if user is authenticated.
private FirebaseAuth mAuth;
private DatabaseReference userRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.main_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Home");
mAuth = FirebaseAuth.getInstance();
userRef = FirebaseDatabase.getInstance().getReference().child("Users");
}
//onstart method used to check if the user is registered or not
@Override
protected void onStart()
{
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser ==null){
SendUserToLoginActivity();
}
else{
//checking if the user exists in the firebase database
CheckUserExistence();
}
}
private void CheckUserExistence()
{
//get the user id
final String currentUserId = mAuth.getCurrentUser().getUid();
userRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{
if (!dataSnapshot.hasChild(currentUserId)){
//user is authenticated but but his record is not present in real time firebase database
SendUserToStepTwoAuthentication();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void SendUserToStepTwoAuthentication()
{
Intent steptwoIntent = new Intent(MainActivity.this, StepTwoAuthentication.class);
steptwoIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(steptwoIntent);
finish();
}
private void SendUserToLoginActivity()
{
Intent loginIntent = new Intent(MainActivity.this, Login.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(loginIntent);
finish();
}
}
view raw Home.java hosted with ❤ by GitHub

Explanation of methods.

mAuth = FirebaseAuth.getInstance();
mAuth = FirebaseAuth.getInstance();
userRef =FirebaseDatabase.getInstance().getReference().child("Users");

Gets the default Firebase Database instance. In this case it creates an instance once a user registers.

//get reference
//import statement
import com.google.firebase.database.DatabaseReference;
//crating an object of the method
userRef = FirebaseDatabase.getInstance().getReference()

Database Reference for the database root node.

//get current user
FirebaseUser currentUser = mAuth.getCurrentUser();

This method gets the user who have just logged in.

//createUserWithEmailAndPassword
mAuth.createUserWithEmailAndPassword(Email,Password)
  .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
  @Override
public void onComplete(@NonNull Task<AuthResult> task) {
   //checking if the task is sucessful
   if (task.isSuccessful()){
   SenduserToSTepTwoAuthentication();
   Toast.makeText(Register.this, "You have passed the first step authentication...", Toast.LENGTH_SHORT).show();
   loadingBar.dismiss();
  }
  else{
  String message = task.getException().getMessage();
   Toast.makeText(Register.this, "error occured" + message, Toast.LENGTH_SHORT).show();                                   }
  loadingBar.dismiss();
}
});

Creates a new user. Uses email and password.

//sign in with email and password
mAuth.signInWithEmailAndPassword(email,password)
           .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
               @Override
               public void onComplete(@NonNull Task<AuthResult> task) {

                   if (task.isSuccessful()){
                       SendUserToMainActivity();
                       Toast.makeText(Login.this, "You are logged in successful", Toast.LENGTH_SHORT).show();
                       loadingBar.dismiss();
                   }
                   else
                   {
                       String message = task.getException().getMessage();
                       Toast.makeText(Login.this, "error occurred" +message, Toast.LENGTH_SHORT).show();
                       loadingBar.dismiss();
                   }

               }
           });

Allow user to login. Uses email and password.

Intents

We are going to use intents to navigate through project activities. Check more about Implicit Intent and Explicit Intents.
Import statement for intent is as shown below.

import android.content.Intent;

Creating the intent.

Intent mainIntent = new Intent(Register.this,MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);

Adding a Progress bar

Let’s add a progress bar. This is to allow a user to know what’s happening as he waits to login.
Import statement.

import android.app.ProgressDialog;

Initializing and creating an instance

 loadingBar =new ProgressDialog(this);

setting the loading bar details and dismissing it.

 //progress bar
            loadingBar.setTitle("Log In");
            loadingBar.setMessage("please wait...");
            loadingBar.show();
            loadingBar.setCanceledOnTouchOutside(true);
//dismissing progress bar
 loadingBar.dismiss();

By this we have completed our two-step authentication signup system with Firebase. Click on the Run button and Run the application on your android phone but you can also install an android emulator on the android studio.

Reflective Analysis

After doing this project, I learned more about how Firebase services. It has very strong services. It can help you create real-time quality apps. It’s very easy to store user sessions.

Future Directions

  1. Add Phone Number Authentication allowing you to receive a text message to verify your phone number.
  2. Add email link authentication. To enable the validity of user emails we can allow Firebase to send an email verification link.

Learning Strategies and Tools

There are a lot of learning tools online, I would recommend the following:

I used the learning tools above. I also used PDF documentations to achieve this. Anytime I faced some bugs, I would use stack overflow to check for solutions. I was able to work with Intents.
Make sure you have an active internet connection since Firebase is an online database.
It took me a total of 12 hours to finish the project and the blog.

Get the complete project from GitHub
Happy Coding!!

Hire the author: Moses N