The KickStarter
Published in

The KickStarter

Android user authentication using Firebase with Spring boot backend — Part 1

Photo by Daniel Romero on Unsplash

Architecture is an indispensable part of software development. Taking the wise decisions in the early stages of your product development lifecycle will save you a lot of money. Most importantly a well architected solution will protect a company from the grudges of disgruntled software developers.

It is often the case that you might want to provide user specific content or features in your android app. A social networking app, a video backup tool, a fitness app, all of these will require a user authentication. But when an Architect is not aware of options other than oauth we might end up in a rigid solution.

When I said other options I meant Firebase. Firebase is a one stop shop to integrate a wide variety of solutions in your android app like authentication, crash reports, database, etc. In this 2 part article we will see how to integrate Google authentication in your android app. The probability of android users having a Google account is pretty high. So providing ‘Google SignIn’ button in your android app is more than enough to serve the world during your MVP phase.

There are 2 major steps in accomplishing this.

  1. Integrate Firebase in your android app
  2. Integrate Firebase in your Backend for Frontend (BFF)

Integrating Firebase in your android app

Firebase is a tool from Google to build android app infrastructure using ready made tools like Authentication. Firebase behind the scene is run on Google Cloud Platform, so when you create a Firebase project for your android app a GCP project is automatically created.

Create different Firebase projects for each of your environments (DTAP).

https://console.firebase.google.com/

Login using your google account (organisational) into firebase console.

Click on Create a project

If you want to share users between apps and you are providing an ecosystem like services then you can create one project for the whole ecosystem. If you don’t want to share users between apps you can create app specific projects.

I am creating an app specific project for development environment
Enable Google Analytics and Continue
Select Default Account for Firebase and Create project
Once your project is ready click Continue
You can also see the project in GCP console once it is ready

Don’t forget to create Billing alerts for your Firebase projects in GCP.

Click on Authentication and Get started
Select a public facing name for your app which will be displayed in Google login screen

Enable Google Sign-in method. Also ‘support email’ is mandatory for the login to work. Leave rest of the fields for defaults and Save.

You can see that Google is Enabled now

Android Project and Code changes for Authentication

Firstly we will have to add few dependencies in gradle to enable Firebase authentication.

I have created a sample android project with just Main Activity in Android studio.

Before we start with code changes the app needs to be added to Firebase.

Open app module in Gradle window and run signingReport
Copy the SHA1 value from the console output of signingReport

Also copy the package from android manifest and keep it ready for the next step.

Open Project Overview in Firebase.

In Project Overview Click on Android icon to Add an app
Register App using the details collected previously
Download google-services.json and paste it in your app module

Skip the next 2 steps which we will see in detail later. You can click on the app to view the settings.

Click on the Gear icon
You can download the google-services.json anytime from here

Now let’s get back to our code changes.

Add the below dependency in Project build.gradle file

classpath 'com.google.gms:google-services:4.3.4'

Add the below plugin and dependencies in Module build.gradle

Module plugin
Module dependencies

Add the below plugin in build.gradle of the Module.

id 'com.google.gms.google-services'

Add the below dependencies in build.gradle of the Module.

implementation platform('com.google.firebase:firebase-bom:26.1.1')
implementation 'com.google.firebase:firebase-auth'
implementation 'com.google.android.gms:play-services-auth:19.0.0'

Now let’s add the Google SignIn button and a Logout button to our main 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">

<com.google.android.gms.common.SignInButton
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:colorScheme="dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/logoutButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:clickable="true"
android:contentDescription="Logout"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="@android:drawable/ic_lock_power_off" />

</androidx.constraintlayout.widget.ConstraintLayout>

Open MainActivity.java and paste the below code for SignIn and Logout.

package com.softwok.softwoktutorialapp;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.tasks.Task;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.GoogleAuthProvider;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private static final int RC_SIGN_IN = 9001;
private FirebaseAuth mAuth;
private GoogleSignInClient mGoogleSignInClient;

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

SignInButton loginButton = findViewById(R.id.loginButton);
loginButton.setOnClickListener(this);

FloatingActionButton logoutButton = findViewById(R.id.logoutButton);
logoutButton.setOnClickListener(this);

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();

mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

mAuth = FirebaseAuth.getInstance();
if (mAuth.getCurrentUser() == null) {
setLoggedOutUi();
} else {
setLoggedInUi();
}
}

@Override
public void onClick(View v) {
if (v.getId() == R.id.loginButton) {
Log.i(TAG, "loginButton Clicked");
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
} else if (v.getId() == R.id.logoutButton) {
Log.i(TAG, "logoutButton Clicked");
signOut();
}
}

private void firebaseAuthWithGoogle(String idToken) {
AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.i(TAG, "signInWithCredential:success");
setLoggedInUi();
Snackbar.make(findViewById(android.R.id.content),
"Login successful", Snackbar.LENGTH_LONG).show();
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.getException());
Snackbar.make(findViewById(android.R.id.content),
"Login failed", Snackbar.LENGTH_LONG).show();
}
});
}

private void signOut() {
// Firebase sign out
mAuth.signOut();

// Google sign out
mGoogleSignInClient.signOut().addOnCompleteListener(this,
task -> {
Log.i(TAG, "signOut:success");
setLoggedOutUi();
Snackbar.make(findViewById(android.R.id.content),
"Logout successful", Snackbar.LENGTH_LONG).show();
});
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = task.getResult(ApiException.class);
if (account == null) {
throw new ApiException(Status.RESULT_INTERNAL_ERROR);
}
Log.i(TAG, "firebaseAuthWithGoogle:" + account.getId());
firebaseAuthWithGoogle(account.getIdToken());
} catch (ApiException e) {
// Google Sign In failed, update UI appropriately
Log.w(TAG, "Google sign in failed", e);
Snackbar.make(findViewById(android.R.id.content),
"Login failed", Snackbar.LENGTH_LONG).show();
}
}
}

private void setLoggedInUi() {
findViewById(R.id.loginButton).setVisibility(View.INVISIBLE);
findViewById(R.id.logoutButton).setVisibility(View.VISIBLE);
}

private void setLoggedOutUi() {
findViewById(R.id.logoutButton).setVisibility(View.INVISIBLE);
findViewById(R.id.loginButton).setVisibility(View.VISIBLE);
}
}

Most important step after this is to Build the project to see if you have skipped any step which might have caused a compile error.

Most often developers forget to paste the google-services.json in app module.

Login Flow in action

Login flow of the rendered Application

--

--

--

A place for passionate writers, innovators, entrepreneurs, digital marketers, side hustlers, and anyone who is ready to help people solve their problems.

Recommended from Medium

A safer way to collect flows from Android UIs

Animated Folding Cell in Android Studio (JAVA)

Integrating HUAWEI Location Kit Using Unity

Dagger navigation support in Android Studio

Using CameraX Exposure Compensation API

Illustration of a tan hand with blue nail polish holding a phone with an image on it

Flutter java.lang.RuntimeException: java.lang.RuntimeException: Duplicate class

How to create Rotating Text in android | Android Studio | Java

Integrating Huawei Location kit using Flutter (Cross Platform)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Richy Great

Richy Great

Father, Software Architect and a Story teller

More from Medium

How to Implement a Voice Changer Capability

Firebase Sign In Android + Saving user’s data in Realtime Database + Saving user’s session

Network Request Error Handling on Web & Mobile Application

How Doma Writes Declarative Code with Material UI