Android Firebase Authentication with Google SignIn

Gino Osahon
AndroidPub
Published in
11 min readMar 10, 2017

--

Hi Android Developers, this is actually my first technical write-up in a series i believe to come. I’ll be taking you through a step by step process on how to implement Firebase Authentication using Google Login.

First what is Firebase?

According to wikipedia, Firebase is a mobile and web application platform with tools and infrastructure designed to help developers build high-quality apps. Firebase is made up of complementary features that developers can mix-and-match to fit their needs. Services provided by Firebase that can help developers build and launch applications faster include:

  1. Cloud Messaging
  2. Authentication
  3. Realtime Database
  4. Storage
  5. Hosting
  6. Crash Reporting to keep your apps stable and free from bugs.
  7. Test Lab to deliver high quality apps.

This tutorial is going to focus on the Authentication service provided by Firebase using Google SignIn and Firebase Realtime Database in Android Applications.

Authentication is the process of identifying an individual, usually based on a username and password before they can access certain resources in our case mobile application resources like data and other information (Authentication is simply the SignIn Process for Apps)

Firebase Realtime database is a NoSQL Cloud database that synced data across all clients for example, web, mobile and other clients and this happens in real time and even when the client is offline, the data remains available.

How to add Firebase Google Login For Authentication.

Follow the below steps to do this:

  1. Visit the Firebase Website firebase.google.com and create a firebase account to start with. Go to Firebase console and click the “Create New Project” Button.
  2. The Create a project window appears and you are required to enter your project name and your Country/Region, Click Create project to proceed.

3. In the next screen choose “Add Firebase to your Android App” and then add the package details and Debug signing certificate SHA-1 key. Click here for a tutorial on Getting Android Debug Keystore SHA1 Fingerprint:

After clicking ADD APP, in the next page, you will be asked to download the google-services.json file. Please, download it to your computer. We will add it to our android app later. After this, you will be taken to your project Dashboard.

4. In the project Dashboard, click the Authentication in the Menu on the left of the page, then click the SIGN-IN METHOD, you will be taken to a page where you can enable and disable different SignIn providers that Firebase Support, go ahead and Enable Google SignIn and then click save.

5. Create Android Firebase Login App in Android Studio.

Let’s create the Android Application that will connect to Firebase for user authentication using Firebase Google Login.

Steps to creating a project on Android Studio

  1. Launch Android Studio and Go to File → New → New Project and enter your Application Name.
  2. Enter company domain, this is used to uniquely identify your App’s package worldwide. Remember to use the same package name as used in the firebase console.
  3. Choose project location and minimum SDK and on the next screen choose Empty Activity, Then Click on Next.
  4. Choose an Activity Name. Make sure Generate Layout File check box is selected, Otherwise we have to generate it ourselves.Then click on Finish. We have used the Activity Name as MainActivity since this will be the default screen when the user opens the app for the first time.

Gradle will configure and build your project and resolve the dependencies, Once it is complete proceed for next steps.

Add Permissions and Dependencies

  1. After Gradle syncs the project, add the google-services.json file that you downloaded while creating a new project on the Firebase console to your project’s app folder as shown below. You can drag the file and put it inside the Android app module folder directly into android studio or you can simply copy the file and paste it inside the Android Studio Project App directory on your computer.

2. Since we need to connect to the Network while authenticating, you’ll need to add the Internet permission in your AndroidManifest.xml file which is more like a configuration file for your App.

AndroidManifest.xml file

<uses-permission android:name=”android.permission.INTERNET”/>

3. open your project’s build.gradle file from the project’s home directory and add the following dependency. Please note that i’m not talking about the module or app’s build.gradle file, we’ll get to that in the next step

Build.gradle file

classpath ‘com.google.gms:google-services:3.0.0’

4. Next, open your app’s build.gradle from the and add the following at the end of the file.

Build.gradle

apply plugin: ‘com.google.gms.google-services’

5. Also add the following dependency in the dependency section.

compile ‘com.google.firebase:firebase-core:10.2.0’compile ‘com.google.firebase:firebase-auth:10.2.0’compile ‘com.google.android.gms:play-services-auth:10.2.0’

After adding these dependencies, Android Studio would want to sync, make sure you are connected to the internet so Android Studio can download these used dependencies.

So let’s start coding the functionalities:

Open activity_main.xml file in the res/layout folder and add the following code. Since we are going to be displaying the username and email of the signed in user in a NavigationDrawer header view, we’ll just have only the Custom Google SignIn Button on this layout.

<?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:layout_width=”match_parent”android:layout_height=”match_parent”android:paddingBottom=”@dimen/activity_vertical_margin”android:paddingLeft=”@dimen/activity_horizontal_margin”android:paddingRight=”@dimen/activity_horizontal_margin”android:paddingTop=”@dimen/activity_vertical_margin”android:orientation=”vertical”android:gravity=”center”tools:context=”com.tutorial.authentication.MainActivity”><com.google.android.gms.common.SignInButtonandroid:id=”@+id/login_with_google”android:layout_width=”match_parent”android:layout_height=”wrap_content” /></LinearLayout>

Now open your MainActivity.java in the App/Java folder, create a method called configureSignIn, outside the onCreate() method and put in the below codes. then call that method in the onCreate method of the class. Please, click here to view the project on github, check there for other resources required to build this application. For example the MainActivity.class extends another class called BaseActivity which will be written short.

we need to configure Google Sign-In in order to be able to get the user data. So, we create a GoogleSignInOptions object with the requestEmail option.

Add this code to the MainActivity Class:

// This method configures Google SignInpublic void configureSignIn(){// Configure sign-in to request the user’s basic profile like name and emailGoogleSignInOptions options = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build();// Build a GoogleApiClient with access to GoogleSignIn.API and the options above.mGoogleApiClient = new GoogleApiClient.Builder(this).enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */).addApi(Auth.GOOGLE_SIGN_IN_API, options).build();}

Next, Add a signIn() method that will be called when the Sign In Button is clicked in the view, this will prompt the user to select a Google account before the authentication process begins. this method will handle sign-in by creating a sign-in intent with the getSignInIntent() method, and starting the intent with startActivityForResult().

private void signIn() {Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);startActivityForResult(signInIntent, RC_SIGN_IN);}

Please note that if you don’t have other extended or all the resources for this project, you’ll be getting some errors by just running the piece of codes in this article, so it’s good to either open the project source code down while reading this tutorial or after reading, make sure you check out the project REPO ON GITHUB. Some instance variables are declared in the class for example mGoogleApiClient and others.

After the user selects an account and the process of authentication with Google begins, the result will be made available in the onActivityResult() as stated in the piece of code below. When the signIn button is clicked, the user will first be authenticated with Google and if that is successful, we’ll now authenticate the user with Firebase after saving user data to SharedPreference, so we can have access to them for display in the Header view of our Navigation Drawer Activity. So it’s a 2 stage authentication, the 1st stage is with Google and the Second with Firebase. So i guess this provides a double and secure authentication process.

// This IS the method where the result of clicking the signIn button will be handled@Overrideprotected 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) {GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);if (result.isSuccess()) {// Google Sign In was successful, save Token and a state then authenticate with FirebaseGoogleSignInAccount account = result.getSignInAccount();idToken = account.getIdToken();name = account.getDisplayName();email = account.getEmail();photoUri = account.getPhotoUrl();photo = photoUri.toString();// Save Data to SharedPreferencesharedPrefManager = new SharedPrefManager(mContext);sharedPrefManager.saveIsLoggedIn(mContext, true);sharedPrefManager.saveEmail(mContext, email);sharedPrefManager.saveName(mContext, name);sharedPrefManager.savePhoto(mContext, photo);sharedPrefManager.saveToken(mContext, idToken);//sharedPrefManager.saveIsLoggedIn(mContext, true);AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);firebaseAuthWithGoogle(credential);} else {// Google Sign In failed, update UI appropriatelyLog.e(TAG, “Login Unsuccessful. “);Toast.makeText(this, “Login Unsuccessful”, Toast.LENGTH_SHORT).show();}}}

Next, after authenticating with Google, it’s now time to authenticate with Firebase. Before we proceed, we should declare the instance of FirebaseAuth object and AuthStateListener which listens for changes in the signed in user state.

So declare these as instance variables:

private FirebaseAuth mAuth;private FirebaseAuth.AuthStateListener mAuthListener;

Then, in the onCreate() method, we’ll need to initialize the FirebaseAuth instance and the AuthStateListener method so we can listen and track whether the user is signed in or out.

mAuth = com.google.firebase.auth.FirebaseAuth.getInstance();//this is where we start the Auth state Listener to listen for whether the user is signed in or notmAuthListener = new FirebaseAuth.AuthStateListener(){@Overridepublic void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {// Get signedIn userFirebaseUser user = firebaseAuth.getCurrentUser();//if user is signed in, we call a helper method to save the user details to Firebaseif (user != null) {// User is signed increateUserInFirebaseHelper();Log.d(TAG, “onAuthStateChanged:signed_in:” + user.getUid());} else {// User is signed outLog.d(TAG, “onAuthStateChanged:signed_out”);}}};

If the user is successfully authenticated by Firebase, we’ll now call the createUserInFirebaseHelper(); method that saves the user data to our own Firebase Database.

This approach of saving the user data to our own Firebase is a good practice after authentication so we can have our own copy of the users details persisted to Firebase database. So from onAuthStateChanged method, we’ll call a helper method that will now take the user details mainly username, photo URL and email and then save them to Firebase Database.

So before you look at the createUserInFirebaseHelper() method that saves data to Firebase, i want you to know that we might be going outside the scope of this tutorial which is simply Authentication with Google and Firebase. Now, we are dabbing into inserting data into Firebase database, which is a topic of it’s own. I’m just implementing this here as a good practice but there is more you need to know about Inserting and selecting from Firebase database. I hope to in my next article, write a step by step guide on inserting and selecting from Firebase.

You need to have the URL to your Firebase database, add a listener to the location and onDataChange, you insert the data by passing an object containing the information you want to save. Please don’t get confused here, i promise to do an article as stated above that will deal extensively on this.

//This method creates a new user on our own Firebase database//after a successful Authentication on Firebase//It also saves the user info to SharedPreferenceprivate void createUserInFirebaseHelper(){//Since Firebase does not allow “.” in the key name, we’ll have to encode and change the “.” to “,”// using the encodeEmail method in class Utilsfinal String encodedEmail = Utils.encodeEmail(email.toLowerCase());//create an object of Firebase database and pass the the Firebase URLfinal Firebase userLocation = new Firebase(Constants.FIREBASE_URL_USERS).child(encodedEmail);//Add a Listerner to that above locationuserLocation.addListenerForSingleValueEvent(new com.firebase.client.ValueEventListener() {@Overridepublic void onDataChange(com.firebase.client.DataSnapshot dataSnapshot) {if (dataSnapshot.getValue() == null){/* Set raw version of date to the ServerValue.TIMESTAMP value and save into dateCreatedMap */HashMap<String, Object> timestampJoined = new HashMap<>();timestampJoined.put(Constants.FIREBASE_PROPERTY_TIMESTAMP, ServerValue.TIMESTAMP);// Insert into Firebase databaseUser newUser = new User(name, photo, encodedEmail, timestampJoined);userLocation.setValue(newUser);Toast.makeText(MainActivity.this, “Account created!”, Toast.LENGTH_SHORT).show();// After saving data to Firebase, goto next activityIntent intent = new Intent(MainActivity.this, NavDrawerActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);finish();}}@Overridepublic void onCancelled(FirebaseError firebaseError) {Log.d(TAG, getString(R.string.log_error_occurred) + firebaseError.getMessage());//hideProgressDialog();if (firebaseError.getCode() == FirebaseError.EMAIL_TAKEN){}else {Toast.makeText(MainActivity.this, firebaseError.getMessage(), Toast.LENGTH_SHORT).show();}}});}

Next, after successfully inserting into our Firebase database, we move to the second Activity where we’ll display user data. The below piece of code from the above method moves us to the second Activity:

/ After saving data to Firebase, goto next activityIntent intent = new Intent(MainActivity.this, NavDrawerActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);finish();

Don’t forget the part that kicks of this whole process which is setting an onClicklisterner on the Google signIn Button, when this button is clicked, the signIn() method is called and the user is prompted to select an account:

mSignInButton = (SignInButton) findViewById(R.id.login_with_google);mSignInButton.setSize(SignInButton.SIZE_WIDE);mSignInButton.setOnClickListener(this);@Overridepublic void onClick(View view) {Utils utils = new Utils(this);int id = view.getId();if (id == R.id.login_with_google){if (utils.isNetworkAvailable()){signIn();}else {Toast.makeText(MainActivity.this, “Oops! no internet connection!”, Toast.LENGTH_SHORT).show();}}}

Next, in the onCreate() method of the second Activity, we get the data stored from SharedPreference. SharedPreference stores data as key value pairs in the application Context and makes it available within that application but loses its data when the user logs out of the app, that’s why we are saving our own copy in our database.

The below code gets a handle to the views in the layout, get’s data from sharedPreferences and sets them to the Header view of the Navigation for display. Please take a look at the GITHUB REPO for the complete classes and other resources.

mFullNameTextView = (TextView) header.findViewById(R.id.fullName);mEmailTextView = (TextView) header.findViewById(R.id.email);mProfileImageView = (CircleImageView) header.findViewById(R.id.profileImage);// create an object of sharedPreferenceManager and get stored user datasharedPrefManager = new SharedPrefManager(mContext);mUsername = sharedPrefManager.getName();mEmail = sharedPrefManager.getUserEmail();String uri = sharedPrefManager.getPhoto();Uri mPhotoUri = Uri.parse(uri);mFullNameTextView.setText(mUsername);mEmailTextView.setText(mEmail);Picasso.with(mContext).load(mPhotoUri).placeholder(android.R.drawable.sym_def_app_icon).error(android.R.drawable.sym_def_app_icon).into(mProfileImageView);

Next, the below code in the second activity, set’s up the NavigationDrawer and the data is displayed on the Header View of the NavigationDrawer:

// Initialize and add Listener to NavigationDrawerpublic void initNavigationDrawer(){navigationView = (NavigationView) findViewById(R.id.navigation_view);navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(MenuItem item) {int id = item.getItemId();switch (id){case R.id.freebie:Toast.makeText(getApplicationContext(),”Home”,Toast.LENGTH_SHORT).show();drawerLayout.closeDrawers();break;case R.id.payment:Toast.makeText(getApplicationContext(),”Settings”,Toast.LENGTH_SHORT).show();drawerLayout.closeDrawers();break;case R.id.trip:Toast.makeText(getApplicationContext(),”Trash”,Toast.LENGTH_SHORT).show();drawerLayout.closeDrawers();break;case R.id.logout:signOut();drawerLayout.closeDrawers();break;case R.id.tips:Toast.makeText(getApplicationContext(),”Trash”,Toast.LENGTH_SHORT).show();drawerLayout.closeDrawers();break;}return false;}});//set up navigation drawerdrawerLayout = (DrawerLayout) findViewById(R.id.drawer);ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close){@Overridepublic void onDrawerClosed(View drawerView) {super.onDrawerClosed(drawerView);}@Overridepublic void onDrawerOpened(View drawerView) {super.onDrawerOpened(drawerView);}};drawerLayout.addDrawerListener(actionBarDrawerToggle);actionBarDrawerToggle.syncState();}

Finally, we create the SignOut method to enable user logout of the app:

//method to logoutprivate void signOut(){new SharedPrefManager(mContext).clear();mAuth.signOut();Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(new ResultCallback<Status>() {@Overridepublic void onResult(@NonNull Status status) {Intent intent = new Intent(NavDrawerActivity.this, MainActivity.class);startActivity(intent);}});}

Here is the complete code for the project.

Now, run the app and click on Google Sign In Button to authenticate using Firebase Google Login. It should show a popup with available google account Click on your google account and the Firebase Google Login App should display your Display name, photo and Email Address on the Header View of the Navigation Drawer in the second activity.

However, if you like this article and want to encourage me to write more articles, you can donate to this ETH, USDC and USDT Address on the Ethereum network: 0xfd446002b2979559ef4Cd06e5DCC84bbCC6b49D3

--

--