Android Facebook Login

Filed Under: Android
android-login-with-fb-choose-facebook-login

Today we will learn how to integrate Facebook login in android applications. You must have seen Facebook login as an easier way to create account in many applications.

Android Facebook Login

Many applications use Login With Facebook to register users in their applications. For the login with Facebook to work, we must have a unique ID for our android application which communicates with the Facebook server.

Let’s start with my creating a new empty Android Studio project.

Now before we write any piece of code, we need to register our application as demonstrated below.

Registering Your Facebook Application

Login using your Facebook account to: https://developers.facebook.com/apps/.

android login with Facebook homepage

Now create a new app. And set the app name and the email id as shown in the below pic.

android Facebook login app name and contact email

Note: Facebook doesn’t allow us to set app names which contain the keyword fb/facebook etc. Hence we’d set the app name to TestTutorial. We’ll need to set up the same name in the strings.xml app_id string of our Android Studio Project.

You shall see the dashboard in the next screen. Choose Facebook Login Setup and select the platform as Android as shown in the below images.

android Facebook login setup

android login with Facebook choose platform

Select Android

From the next screen, instead of downloading the Facebook SDK, import the SDK using the gradle dependency.
For that, add the following dependencies in your app‘s build.gradle.


buildscript { 
repositories {
mavenCentral()
}
} 

Use the latest version of the SDK dependency.


implementation 'com.facebook.android:facebook-android-sdk:4.31.0'

To check that the sdk is successful added in our project add the following import statements in your MainActivity.java class file as shown below. If there’s no error, the build was successful.


import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;

Add your Facebook App ID
The App ID present in the Facebook developers application dashboard needs to be added in the strings.xml in our Android Studio Project.


<string name="facebook_app_id">894882580618030</string>

Enter your package name and default activity name with the fully qualified path as shown below. After saving click on Use this package name to confirm.
android login with facebook
S

The next window asks for the setting up the key hashes. That can be done by running the following commands on mac terminal/windows cmd:


//Mac cmd
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

//Windows cmd
keytool -exportcert -alias androiddebugkey -keystore "C:\Users\USERNAME\.android\debug.keystore" | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" sha1 -binary | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" base64

Copy and paste the hash key in the Key hashes field below.
You will need to provide a key hash for every device you run this application on till it is in development mode.

Enable Single Sign-on on the next segment.

Back to Android Studio, add the following line in strings.xml file:


<string name="fb_login_protocol_scheme">fb204127990172423</string>

The number followed by fb is our APP ID above.

Enable internet permissions in the AndroidManifest.xml file by adding the following line in the manifest element.


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

Now add the following code inside the application tag in the Manifest.


<meta-data android:name="com.facebook.sdk.ApplicationId" 
        android:value="@string/facebook_app_id"/>
    
    <activity android:name="com.facebook.FacebookActivity"
        android:configChanges=
                "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
        android:label="@string/app_name" />
    <activity
        android:name="com.facebook.CustomTabActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="@string/fb_login_protocol_scheme" />
        </intent-filter>
    </activity>

Let’s get onto the business end now that the registration and setup is done.
In the following app we’ll add a login with Facebook button which on click would retrieve and display the user’s name, email and profile picture.
We’ll be seeing how the Facebook SDK does all of this.

Android Facebook Login Project Structure

android Facebook integration

Android Facebook Integration Code

The code for the activity_main.xml layout file is given below.


<?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:background="#222"
    android:gravity="center"
    android:orientation="vertical"
    tools:context="com.journaldev.loginwithfbexample.MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:src="@mipmap/ic_launcher"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <TextView
        android:id="@+id/txtUsername"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Username"
        android:padding="8dp"
        android:textColor="#FFF" />

    <TextView
        android:id="@+id/txtEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Email Address"
        android:padding="8dp"
        android:textColor="#FFF" />


    <com.facebook.login.widget.LoginButton
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="15dp"
        android:paddingTop="15dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

We’ve changed our layout to a LinearLayout, to stack the views vertically.

The code for the MainActivity.java class is given below.


package com.journaldev.loginwithfbexample;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.Profile;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.squareup.picasso.Picasso;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Arrays;


public class MainActivity extends AppCompatActivity {

    LoginButton loginButton;
    CallbackManager callbackManager;
    ImageView imageView;
    TextView txtUsername, txtEmail;

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

        loginButton = findViewById(R.id.login_button);
        imageView = findViewById(R.id.imageView);
        txtUsername = findViewById(R.id.txtUsername);
        txtEmail = findViewById(R.id.txtEmail);

        boolean loggedOut = AccessToken.getCurrentAccessToken() == null;

        if (!loggedOut) {
            Picasso.with(this).load(Profile.getCurrentProfile().getProfilePictureUri(200, 200)).into(imageView);
            Log.d("TAG", "Username is: " + Profile.getCurrentProfile().getName());

            //Using Graph API
            getUserProfile(AccessToken.getCurrentAccessToken());
        }

        loginButton.setReadPermissions(Arrays.asList("email", "public_profile"));
        callbackManager = CallbackManager.Factory.create();

        loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                // App code
                //loginResult.getAccessToken();
                //loginResult.getRecentlyDeniedPermissions()
                //loginResult.getRecentlyGrantedPermissions()
                boolean loggedIn = AccessToken.getCurrentAccessToken() == null;
                Log.d("API123", loggedIn + " ??");

            }

            @Override
            public void onCancel() {
                // App code
            }

            @Override
            public void onError(FacebookException exception) {
                // App code
            }
        });

    }

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

    private void getUserProfile(AccessToken currentAccessToken) {
        GraphRequest request = GraphRequest.newMeRequest(
                currentAccessToken, new GraphRequest.GraphJSONObjectCallback() {
                    @Override
                    public void onCompleted(JSONObject object, GraphResponse response) {
                        Log.d("TAG", object.toString());
                        try {
                            String first_name = object.getString("first_name");
                            String last_name = object.getString("last_name");
                            String email = object.getString("email");
                            String id = object.getString("id");
                            String image_url = "https://graph.facebook.com/" + id + "/picture?type=normal";

                            txtUsername.setText("First Name: " + first_name + "\nLast Name: " + last_name);
                            txtEmail.setText(email);
                            Picasso.with(MainActivity.this).load(image_url).into(imageView);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }
                });

        Bundle parameters = new Bundle();
        parameters.putString("fields", "first_name,last_name,email,id");
        request.setParameters(parameters);
        request.executeAsync();

    }
}

In the above code:

  • Facebook SDK auto initializes in the class. So no need to explicitly initialize it.
  • We’ve set the readPermissions to email and public_profile. Typically, Facebook provides three permissions by default: email, public_profile, user_friends. Where user_friends would display the friends using this app.
  • We instantiate a CallBackManager to invoke the register callback on LoginButton click.
  • If the result of button click is a success, LoginResult class is returned. Through it we can access the access token, granted and revoked permissions.
  • onActivityResult gets the response of the Login and passes it to registerCallback method.
  • The AccessToken is autosaved in the application data (SharedPreferences) implicitly.
    So, everytime the activity is created, we call AccessToken.getCurrentAccessToken(). If it is null, the user has to sign in again.
  • Similarly, if the Profile class returns the current user through which we can retrieve the profile name, picture.
  • The Facebook Graph API is used to retrieve user info. It works by passing a Bundle of parameters as keys to the GraphRequest. The GraphRequest, on execution, should return the relevant info values based on the keys specified if they meet the permissions. The result is returned in the form of a JSON.
  • We’ve used Picasso to display the image url in the ImageView.
    For that we need to add the following dependency:

    implementation 'com.squareup.picasso:picasso:2.5.2'

Listening for Changes on LoginButton click
AccessToken Tracker makes it possible to listen for changes on button click.
accessToken2 is the latest access token. accessToken is the older one.

Android Facebook Login App Output

The output of the above application in action is given below.
facebook integration in android app

Note: If you get an error like this:
android login with fb invalid hash

Add the hash mentioned in your respective screen in the App’s Dashboard on Facebook Developers Page.
You need to add the hash values for all such devices using the login with Facebook in development mode.

Adding More Permissions for Facebook Integration

To add and use more permissions in your application, head on to the app review section on the dashboard in the Facebook developer page. Every new permission must be approved by Facebook first.

android Facebook integration adding permissions app review

This brings an end to this tutorial. You can download the Android LoginWithFbExample Project from the link below. Create your own APP ID and replace it with the one in strings.xml!

Comments

  1. apoorv varshney says:

    i used the above code but it does not how profile image,name and email only login and log out works.please help me to get the image ,name and email also .
    i have implemented picasso dependencies.

  2. Rahul says:

    Facebook Login and logout not working properly.
    if i click on login then it does not load data immediately it loads data when i re-open app and same for logged out it logged out properly when i reopen app.
    please help me. working on past three days on same error.

    1. siddharth says:

      did you solve the problem

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages