Click here to Skip to main content
15,881,610 members
Articles / Mobile Apps / Android

Firebase Authentication by Example with Android

Rate me:
Please Sign up or sign in to vote.
4.67/5 (5 votes)
23 Feb 2017CPOL7 min read 38.5K   8   6
This post is a step by step tutorial on how to implement Firebase Authentication in Android.

This post is a step by step tutorial on how to implement Firebase Authentication in Android. This post is a continuation of my Firebase Realtime Database tutorial, and I encourage you to read that tutorial first if you are new to Firebase. When we implement authentication to our app, what we are in effect doing is putting our app behind a wall such that anyone requiring access to the app or content will have to go through a login process. An effective authentication process, therefore involves two steps, the authentication process and the handling of successful authentication. We will begin with the later which is handling of a successful Firebase authentication.

In this post, we will continue with the Pronto Diary project that was created in Firebase database tutorial.

Add Firebase Authentication to Android Project

There are two steps to add Firebase authentication to an Android Studio project, first you have to enable the sign-in method that you want to implement over at Firebase console. For this tutorial, we are going to implement email sign-in and Google sign-in so only those two methods have been enabled like this:

Image 1

Enable Firebase Authentication Method

The next step is to add Firebase authentication to our Android studio project. The best way to do this, is to use the Firebase Android Studio tool. This accomplishes two things: first, it will add Firebase authentication to your google-services.json file and second, it will add the applicable dependencies to your app gradle file. To use the Firebase tool, first make sure that you are logged into Android Studio with the same Google account that you used to create the Firebase project and then click on tools/Firebase like this:

Image 2

Image 3

You also need to click on Connect to Firebase if this app has not been connected to Firebase yet. Then, you need to click on Add Firebase authentication like this:

Image 4

Handle Successful Firebase Authentication

We will be implementing the actual authentication workflow in a moment but first, let us handle a successful authentication. If you do not have the source code from the last tutorial, then you can download it below and then follow the steps to handle a successful Firebase authentication.

Download Source Code

Step 1: Require Sign In

Each time Firebase Authentication completes successfully, it will hand over a Firebase User object representing the successfully authenticated user. This user object contains basic information about the logged in user such as name, email, profile image url if any and a proprietary Firebase user id. What you do with this user is up to you, just do not change the user id, you can save this to your own database or do something else. For our demo purposes, we are going to do two things with the user object.

  1. Create a Navigation drawer header displaying the user’s name, email and profile picture.
  2. Create a per user database reference that contains just the user’s data and associate that location (aka folder) with the user.

To do this, we want to erect a login wall in the app launcher Activity DiaryListActivity.java. In the onCreate() method of this class, we want to check if the current user is a valid Firebase User. If the user is not a valid Firebase User, we want to send them to another Activity that handles the authentication, let us called that Activity AuthUiActivity.java. Then, at the top of the Activity named DiaryListActivity.java, define two references for Firebase Authentication and Firebase User like this:

Java
private FirebaseAuth mFirebaseAuth;
 private FirebaseUser mFirebaseUser;

And then, within the onCreate() method, we want to instantiate these two references like this:

Java
mFirebaseAuth = FirebaseAuth.getInstance();
 mFirebaseUser = mFirebaseAuth.getCurrentUser();

Now we want to check if this user object is null, if it is null, then we know that the user does not have a valid admission ticket so we send them to the ticket booth aka AuthUiActivity.java to get authenticated.

Java
if (mFirebaseUser == null){
            //Not signed in, launch the Sign In Activity
            startActivity(new Intent(this, AuthUiActivity.class));
            finish();
            return;
   }

If the user passes the null test, then we can proceed to retrieve their name, email, and picture like below, first we have to add the respective instance variables for mUsername, mPhotoUrl, and mEmailAddress.

Java
if (mFirebaseUser == null){
            //Not signed in, launch the Sign In Activity
            startActivity(new Intent(this, AuthUiActivity.class));
            finish();
            return;
       }else {
            mUsername = mFirebaseUser.getDisplayName();
            mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
            mEmailAddress = mFirebaseUser.getEmail();
        }

As soon as we pass this point, we know that we have a valid FirebaseUser object and we can proceed to use their information to create a Navigation drawer like this:

Java
private void setupNavigationDrawer(Bundle savedInstanceState) {
        mUsername = TextUtils.isEmpty(mUsername) ? ANONYMOUS : mUsername;
        mEmailAddress = TextUtils.isEmpty(mEmailAddress) ? ANONYMOUS_EMAIL : mEmailAddress;
        mPhotoUrl = TextUtils.isEmpty(mPhotoUrl) ? ANONYMOUS_PHOTO_URL : mPhotoUrl;

        IProfile profile = new ProfileDrawerItem()
                .withName(mUsername)
                .withEmail("someemail@gymmail.com")
                .withIcon(mPhotoUrl)
                .withIdentifier(102);

        mHeader = new AccountHeaderBuilder()
                .withActivity(this)
                .withHeaderBackground(R.drawable.header)
                .addProfiles(profile)
                .build();
        mDrawer = new DrawerBuilder()
                .withAccountHeader(mHeader)
                .withActivity(this)
                .withToolbar(toolbar)
                .withActionBarDrawerToggle(true)
                .addDrawerItems(
                        new PrimaryDrawerItem().withName("Journals").withIcon
                        (GoogleMaterial.Icon.gmd_view_list).withIdentifier(Constants.JOURNAL_ENTRIES),
                        new PrimaryDrawerItem().withName("Tags").withIcon
                        (GoogleMaterial.Icon.gmd_folder).withIdentifier(Constants.TAGS),
                        new PrimaryDrawerItem().withName("Logout").withIcon
                        (GoogleMaterial.Icon.gmd_lock).withIdentifier(Constants.LOGOUT),
                        new PrimaryDrawerItem().withName("Delete Account!").withIcon
                        (GoogleMaterial.Icon.gmd_delete).withIdentifier(Constants.DELETE)
                )
}

We are using Mike Penz Navigation Drawer library to create this Navigation Drawer and this takes care of displaying the user’s information. The next thing we want to do with the FirebaseUser object is to update the Journal Entries list such that only the data that belongs to this user is displayed and then when it is time to add data, we want to add the currents users' data to a specific location.

Associate User Data with Firebase User

We need to update Firebase database rules in the Firebase console in order to associate each user with their data. Currently, the database rule is configured for public access like this:

Java
{
  "rules": {
    ".read": true,
    ".write": true
  }
}

We can now update that rule to give each authenticated user a personal node at...

Java
/users/$user_id

...where “$user_id" is the same user Id that is exposed at the Android client. Here is the updated rule.

Java
{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

So, knowing that the user id is in the cloud and the client is consistently unique, we can now create a per user database reference like this:

Java
journalCloudEndPoint =  mDatabase.child("/users/" + 
mFirebaseUser.getUid() + "journalentris");

The above line will create a “users” node (visualize it as a folder) at the root of our cloud database endpoint. This user’s node will contain an entry for each authenticated database user. Under this node is a child node called “journalentries” which will now hold only the Journal Entries of this user. We can now attach a ValueChangedListener to this endpoint like before, and it will only listen for events that are related to the user’s data.

Working with Firebase UI Auth Library

Now that we have handled a successful authentication, we need to now implement the authentication workflow using Firebase Authentication. Thankfully, the Firebase UI library makes it easy to implement authentication. Matter of fact, it is highly recommended by the Firebase documentation to use Firebase UI library because it followed best practices and its open source.

Moreover, the library comes with a sample app that demonstrates most of the common use cases of the library. An easy way to implement Firebase authentication is to copy this sample app, specifically the AuthUiActivity and the SignedInActivity to your project. You will need to copy all the associated resource files – they styles, strings, colors, and layout over and then modify as you see fit once your project recompiles.

For this demo app, we will implement email and Google sign in. If you want to implement other authentication providers such as Facebook and Twitter, then you have to perform additional steps as outlined here.

Show Sign In Screen

We will define the login workflow in the AuthUiActivity. In this class once again, the first thing we need to do is to check if the user is logged-in, if they are, then we can send them back to the DiaryListActivity, if not then we should show the login screen like this.

Java
public class AuthUiActivity extends AppCompatActivity {

    private static final String GOOGLE_TOS_URL = 
    "https://www.google.com/policies/terms/";
    private static final int RC_SIGN_IN = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auth_ui);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FirebaseAuth auth = FirebaseAuth.getInstance();
        if (auth.getCurrentUser() != null) {
            startActivity(new Intent(this, DiaryListActivity.class));
            finish();
        }else {
            showSignInScreen();
        }
    }

    private void showSignInScreen() {
        startActivityForResult(
                AuthUI.getInstance().createSignInIntentBuilder()
                        .setTheme(R.style.GreenTheme)
                        .setProviders(getSelectedProviders())
                        .setTosUrl(GOOGLE_TOS_URL)
                        .setIsSmartLockEnabled(false)
                        .build(),
                RC_SIGN_IN);
    }
}

And with the above lines of code, you are almost done with implementing Firebase Authentication. This code will present the user with this login screen.

Image 5

Firebase UI Auth Login

If the user clicks in either of the login options, the Firebase UI Auth library handles the whole authentication workflow. All your app has to do is wait for the authentication to complete. And once it completes, the result of that authentication is delivered to the onActivityResult() which you have to handle. All you have to do is to check if the authentication is successful and if it is, you can go back to your launcher Activity. You do not have to pass a reference to the user to the next Activity, the Firebase Authentication client handles that. Here is the onActivityResult code:

Java
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) {
            handleSignInResponse(resultCode, data);
            return;
        }

        showSnackbar(R.string.unknown_response);
    }

    @MainThread
    private void handleSignInResponse(int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            Intent in = new Intent(this, DiaryListActivity.class);
            in.putExtra(EXTRA_IDP_RESPONSE, IdpResponse.fromResultIntent(data));
            startActivity(in);
            finish();
            return;
        }

        if (resultCode == RESULT_CANCELED) {
            showSnackbar(R.string.sign_in_cancelled);
            return;
        }

        if (resultCode == ResultCodes.RESULT_NO_NETWORK) {
            showSnackbar(R.string.no_internet_connection);
            return;
        }

        showSnackbar(R.string.unknown_sign_in_response);
    }

Summary

That completes this tutorial on Firebase Authentication. My premium source code and course contain a complete example of implementing Firebase authentication. The actual implementation of the Authentication workflow is made super simple with the Firebase Auth UI. Think of it like implementing in-app purchase, you decide at which point in your app, where a login is required. When a user reaches that point, you send them off to be authenticated. And once that process completes, you can let them continue to use your app.

If for some reason, you have some custom requirement that you want to implement the authentication workflow yourself, this tutorial provides a good walk-through. If you have not done so already, please support me by sharing this post to your social media feed.

The post Firebase Authentication by Example with Android appeared first on Val Okafor.

This article was originally posted at http://valokafor.com/firebase-authentication-android

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) ValOkafor.com
United States United States
My name is Val Okafor, I am a Senior Software Engineer with specialization in Android Development. Learning and problem solving is my passion and I share my Android development knowledge through my blog ValOkafor.com.

My Android courses are the courses I wish I had when I started. I teach Android development in the context of a fully developed Android app. I believe that new Android concepts are better understood if they are presented in the context of creating an app from scratch to finish.

I focus on creating Productivity Android apps and besides Android development I have 7 years’ experience as System Administrator supporting Enterprise applications and 2 years’ experience as a Web Developer building websites using PHP and ASP.Net.

I have worked for corporations such as The Home Depot, American Council on Exercise, Legend3D and HD Supply, Inc. I have a bachelor's degree in Information Technology from National University San Diego, California and a master's degree in Software Engineering from Regis University Denver, Colorado.

I enjoy sharing my extensive work experience through my blog, social media.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Mike (Prof. Chuck)26-May-18 20:18
professionalMike (Prof. Chuck)26-May-18 20:18 
QuestionNull point Exception Pin
nagesh badole5-Oct-17 1:40
nagesh badole5-Oct-17 1:40 
Questionfirebase phone authentication in android Pin
Member 1343483228-Sep-17 0:37
Member 1343483228-Sep-17 0:37 
GeneralVote great and have a question Pin
ly_he16-May-17 20:45
ly_he16-May-17 20:45 
GeneralMy vote of 4 Pin
Muhammad Shahid Farooq1-Mar-17 19:10
professionalMuhammad Shahid Farooq1-Mar-17 19:10 
GeneralMy vote of 5 Pin
Mike (Prof. Chuck)27-Feb-17 5:20
professionalMike (Prof. Chuck)27-Feb-17 5:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.