What is Firebase?

Firebase is a mobile(Android or iOS) and web application development platform that provides a suite of cloud-based tools and services offered by Google.  It is a Backend-as-a-Service(BaaS) that enables developers to build and deploy applications quickly and efficiently, with built-in features for authentication, real-time databases, cloud storage, hosting, and more.

In this tutorial, we'll build a simple Java Android app with Firebase for authentication that allows users to create accounts. sign in and sign out of the accounts. We'll also cover how to use your Android phone as an emulator.

Prerequisites

Before starting this tutorial, you should know the basics of Android app development.

Additionally, you must have the following software installed on your computer:

Step 1: Create a New Android App

Step 2: Run and test the app.

To do this, you can connect a physical Android device or start an emulator.

To use an emulator, follow these steps:

To connect to a physical Android device, follow the following steps:

On your Android device( phone or tablet), open the settings and navigate to `About phone`. Click on 'Software Information'.

N.B.: There are other ways to connect your physical device to your Android studio as an emulator, such as wireless debugging, but in this tutorial, we'll use USB debugging.

Step 3: Create the User Interface

In this step, we'll create the user interface and design. Navigate to the app/res folder; this is where most of the user interface changes will take place.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="slateblue"> #6F58C9</color>
    <color name="black">#FF000000</color>
    <color name="white"> #FFFFFFFF</color>
</resources>


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <stroke
        android:width="2dp"
        android:color="@color/slateblue"/>
    <corners
        android:radius="30dp"/>
</shape>

Step 4: Create new activities.

<activity
            android:name=".LoginActivity"
            android:exported="false" />
        <activity
            android:name=".SignUpActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:exported="false">
        </activity>

Step 5: Edit the activity layout.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textColor="@color/slateblue"
        android:textSize="26sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
 
</androidx.constraintlayout.widget.ConstraintLayout>


<?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=".SignUpActivity">

    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        app:cardCornerRadius="30dp"
        app:cardElevation="20dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_gravity="center_horizontal"
            android:padding="24dp"
            android:background="@drawable/custom_edittext">

            <TextView
                style="@style/TitleText"
                android:text="Sign Up"/>

            <EditText
                style="@style/EditTextView"
                android:id="@+id/signup_email"
                android:hint="Email"
                android:drawableLeft="@drawable/baseline_person_24"
                android:textColor="@color/black" />

            <EditText
                style="@style/EditTextView"
                android:id="@+id/signup_password"
                android:hint="Password"
                android:drawableLeft="@drawable/baseline_lock_person_24"
                android:textColor="@color/black" />

            <Button
                style="@style/ButtonStyle"
                android:id="@+id/signup_button"
                android:text="Sign Up"
                app:cornerRadius = "20dp"
                />

            <TextView
                style="@style/LoginRedirectText"
                android:id="@+id/loginRedirectText"
                android:text="Already a user. Login" />

        </LinearLayout>
    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

<?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"
    android:gravity="center"
    tools:context=".LoginActivity">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        app:cardCornerRadius="30dp"
        app:cardElevation="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_gravity="center_horizontal"
            android:padding="24dp"
            android:background="@drawable/custom_edittext">

            <TextView
                style="@style/TitleText"
                android:text="Login"/>

            <EditText
                style="@style/EditTextView"
                android:id="@+id/login_email"
                android:hint="Email"
                android:drawableLeft="@drawable/baseline_person_24"
                android:textColor="@color/black" />

            <EditText
                style="@style/EditTextView"
                android:id="@+id/login_password"
                android:hint="Password"
                android:drawableLeft="@drawable/baseline_lock_person_24"
                android:textColor="@color/black" />

            <Button
                style="@style/ButtonStyle"
                android:text="Login"
                android:id="@+id/login_button"
                app:cornerRadius="20dp"  />

            <TextView
                style="@style/LoginRedirectText"
                android:id="@+id/signUpRedirectText"
                android:text="Not yet registered? Sign Up" />

        </LinearLayout>
    </androidx.cardview.widget.CardView>

</LinearLayout>

<resources>
    <style name="TitleText">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textSize">36sp</item>
        <item name="android:textAlignment">center</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">@color/slateblue</item>
    </style>

    <style name="EditTextView">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:background">@drawable/custom_edittext</item>
        <item name="android:layout_marginTop">20dp</item>
        <item name="android:padding">8dp</item>
        <item name="android:drawablePadding">8dp</item>
    </style>

    <style name="ButtonStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:textSize">18sp</item>
        <item name="android:layout_marginTop">30dp</item>
        <item name="android:backgroundTint">@color/slateblue</item>
    </style>


    <style name="LoginRedirectText">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_gravity">center</item>
        <item name="android:padding">8dp</item>
        <item name="android:layout_marginTop">10dp</item>
        <item name="android:textColor">@color/slateblue</item>
        <item name="android:textSize">18sp</item>
    </style>


</resources>

Hey guys, you might notice that I left the app:cornerRadius button in the layout files instead of adding it to the styles.xml file. This is because app:cornerRadius attribute is specific to the CardView widget and is not a standard attribute for the Button widget.

Step 6: Setup Firebase Authentication

Note: If you have more than one app on the project, go to the project overview, then click on 'app' and select which app you want to authenticate.

Step 7: Add authentication to the project.

package com.example.firebaseauthapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
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;

public class SignUpActivity extends AppCompatActivity {


  // Declare necessary variables
    private FirebaseAuth auth;
    private EditText signupEmail, signupPassword;
    private Button signupButton;
    private TextView loginRedirectText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up);

        // Initialize the FirebaseAuth instance in onCreate()
        auth = FirebaseAuth.getInstance();
        signupEmail = findViewById(R.id.signup_email);
        signupPassword = findViewById(R.id.signup_password);
        signupButton = findViewById(R.id.signup_button);
        loginRedirectText = findViewById(R.id.loginRedirectText);

        signupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String user = signupEmail.getText().toString().trim();
                String pass = signupPassword.getText().toString().trim();

              // Set up Validation Logic
                if (user.isEmpty()) {
                    signupEmail.setError("Email cannot be empty");
                } else if (pass.isEmpty()) {
                    signupPassword.setError("Password cannot be empty");
                } else {
                    auth.createUserWithEmailAndPassword(user, pass)
                        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                            @Override
                            public void onComplete(@NonNull Task<AuthResult> task) {
                                if (task.isSuccessful()) {
                                    Toast.makeText(SignUpActivity.this, "Signup Successful", Toast.LENGTH_SHORT).show();
                                    startActivity(new Intent(SignUpActivity.this, LoginActivity.class));
                                } else {
                                    Toast.makeText(SignUpActivity.this, "Signup Failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
                }
            }
        });



      // Set up Success and Failure Listeners
        loginRedirectText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(SignUpActivity.this, LoginActivity.class));
            }
        });
    }
}

package com.example.firebaseauthapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;

public class LoginActivity extends AppCompatActivity {

    // Declare necessary variables
    private FirebaseAuth auth;
    private EditText loginEmail, loginPassword;
    private TextView signupRedirectText;
    private Button loginButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        // Initialize Firebase Auth instance
        auth = FirebaseAuth.getInstance();
        loginEmail = findViewById(R.id.login_email);
        loginPassword = findViewById(R.id.login_password);
        loginButton = findViewById(R.id.login_button);
        signupRedirectText = findViewById(R.id.signupRedirectText);

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String email = loginEmail.getText().toString().trim();
                String pass = loginPassword.getText().toString().trim();

                if (email.isEmpty()) {
                    loginEmail.setError("Email cannot be empty");
                } else if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
                    loginEmail.setError("Please enter a valid email");
                } else if (pass.isEmpty()) {
                    loginPassword.setError("Password cannot be empty");
                } else {
                    auth.signInWithEmailAndPassword(email, pass)
                        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
                            @Override
                            public void onSuccess(AuthResult authResult) {
                                Toast.makeText(LoginActivity.this, "Login Successful", Toast.LENGTH_SHORT).show();
                                startActivity(new Intent(LoginActivity.this, MainActivity.class));
                                finish();
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Toast.makeText(LoginActivity.this, "Login Failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });
                }
            }
        });

        signupRedirectText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(LoginActivity.this, SignUpActivity.class));
            }
        });
    }
}

By following these steps, you have successfully integrated Firebase and set up user authentication for your application.

Conclusion

In this tutorial, we used Firebase to add user authentication to our Android Java application. We developed an application where users can create accounts, sign up, and sign out. We also covered how to use an Android phone as an emulator.

To expand your knowledge of Firebase in Android app development, refer to the Android and Firebase documentation.