Android

Tutorial on how to add facebook login to your Android App

Introduction

This section explains how you can create an app with user registration using Facebook Login and Parse Server core features through Back4App.

This is how it will look like:

User Registration with Facebook Login App

At any time, you can access the complete Android Project built with this tutorial at our GitHub repository.

Prerequisites

To complete this tutorial, you need:

  • Android Studio at a version higher than 3.0.
  • An app created on Back4App.
  • An android app connected to Back4app.
  • A device (or virtual device) running Android 4.0 (Ice Cream Sandwich) or newer.

Step 1 - Facebook Set up

To start using Facebook functions, you need to:

  1. Go to the Facebook Developer Website and create an account and an app.
  2. Go to + Add Product > Facebook Login > Quickstart > Android, or click here, and follow the guide paying attention to the following recommendations:

    Here are the following steps included in the Facebook’s Quickstart Guide which you need to follow carefully, as you are not going to follow them exactly like Facebook suggests:

    • In Step 2 of Facebook’s Quickstart Guide, you’ll be asked to add the following code at build.gradle (Project).
      1
      2
      3
      repositories {
         mavenCentral()
      }
      

      But you have already added it in build.gradle (Module: app) while following Install Parse SDK Tutorial, so you don’t need to do this.

    • Also in Step 2, instead of adding
      1
      implementation 'com.facebook.android:facebook-android-sdk:[4,5)'
      

      in the dependencies{} section at build.gradle (Module:app), add the following code in the dependencies{} section at build.gradle (Module:app) (if the implementation is giving errors, try replacing it with compile):

      1
      2
      3
      4
      5
      6
      7
      8
      // update the versions to the latest ones
      compile 'com.parse.bolts:bolts-android:1.4.0'
      compile 'com.parse:parsefacebookutils-v4-android:1.10.4@aar'
      compile 'com.facebook.android:facebook-android-sdk:4.29.0'
      compile fileTree(dir: 'libs', include: ['*.jar'])
      compile fileTree(include: 'Parse-*.jar', dir: 'libs')
      compile fileTree(include: 'ParseFacebookUtilsV4-*.jar', dir: 'libs')
      implementation 'com.google.android.gms:play-services-maps:11.8.0'
      
    • In Step 3, you’ll be asked to add internet permission at application element in /app/manifest/AndroidManifest.xml file, but you have already added it while following Install Parse SDK Tutorial, so you don’t need to do this.
    • In Step 5, you’ll need to provide key hashes and to do that you must have Open SSL installed. Facebook’s Guide doesn’t provide command lines to generate key hashes in Linux, but doing that is simple, as all it requires from you is to open a terminal window and run the following command:
      keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
      
    • Don’t follow the steps of Facebook’s Quickstart Guide right after Step 6.

    The steps not mentioned above should be followed exactly according to the Facebook’s Quickstart Guide.

  1. Go to your App dashboard at Back4App Website and click on Server Settings.
  2. Find the “Facebook Login” block and click on Settings. The “Facebook Login” block looks like this:

    Facebook Login Block at Back4App

  3. Go back to your Android Studio Project, open your strings file: .../app/src/main/res/values/strings.xml, copy your facebook_app_id and paste it in the Facebook appId field of the last page of Back4App that you opened. Lastly, press the + sign and click on save button.

Step 3 - Add provider element in the Manifest file

Go back to your Android Studio Project and inside the application element in /app/manifest/AndroidManifest.xml file, right after the meta data element, add the following code:

1
2
3
4
5
<provider
    android:name="com.facebook.FacebookContentProvider"
    <!--don't forget to put your Facebook App ID in the following link-->
    android:authorities="com.facebook.app.FacebookContentProviderYOUR_FACEBOOK_APP_ID"
    android:exported="true" />

Step 4 - Set up

  1. At the beginning of each Parse activity, import the following:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Front End Dependencies
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    // Parse dependencies
    import com.parse.Parse;
    import com.parse.ParseUser;
    
  2. Then you need to initialize Parse, so in the onCreate method, right before setContentView, use the following in each activity:
    1
    Parse.initialize(this);
    
  3. It’s very important to use the following as a method in each activity to avoid errors with the default Android behavior:
    1
    2
    3
    4
    5
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ParseFacebookUtils.onActivityResult(requestCode, resultCode, data);
    }
    

Step 5 - Log In

  1. Import into your LoginActivity, in addition to the dependencies imported in Step 4:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Front End dependencies
    import android.util.Log;
    import android.widget.Toast;
    // Facebook main dependencies
    import com.parse.ParseFacebookUtils;
    // Facebook Graph API dependencies
    import com.facebook.AccessToken;
    import com.facebook.GraphRequest;
    import com.facebook.GraphResponse;
    // Parse dependencies
    import com.parse.LogInCallback;
    import com.parse.ParseException;
    import com.parse.SaveCallback;
    
  2. Then, in addition to the initialization made in Set 4, you need to initialize ParseFacebookUtils. To do so, in the onCreate method, right before setContentView use:
    1
    ParseFacebookUtils.initialize(this);
    
  3. To implement Facebook Login, simply use the following code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Collection<String> permissions = Arrays.asList("public_profile", "email");
    ParseFacebookUtils.logInWithReadPermissionsInBackground(LoginActivity.this, permissions, new LogInCallback() {
     @Override
     public void done(ParseUser user, ParseException err) {
         if (err != null) {
             ParseUser.logOut();
             Log.e("err", "err", err);
         }
         if (user == null) {
             ParseUser.logOut();
             Toast.makeText(LoginActivity.this, "The user cancelled the Facebook login.", Toast.LENGTH_LONG).show();
             Log.d("MyApp", "Uh oh. The user cancelled the Facebook login.");
         } else if (user.isNew()) {
             Toast.makeText(LoginActivity.this, "User signed up and logged in through Facebook.", Toast.LENGTH_LONG).show();
    
             Log.d("MyApp", "User signed up and logged in through Facebook!");
             getUserDetailFromFB();
         } else {
             Toast.makeText(LoginActivity.this, "User logged in through Facebook.", Toast.LENGTH_LONG).show();
    
             Log.d("MyApp", "User logged in through Facebook!");
             getUserDetailFromParse();
         }
     }
    });
    

    In the example project, this code is placed inside a LOGIN VIA FACEBOOK button callback.

  4. As you can see, there are many more methods included in the code above. The getUserDetailFromFB method is responsible for fetching user details. Here’s the code for this method:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    void getUserDetailFromFB(){
         GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),new GraphRequest.GraphJSONObjectCallback(){
             @Override
             public void onCompleted(JSONObject object, GraphResponse response) {
                 ParseUser user = ParseUser.getCurrentUser();
                 try{
                     user.setUsername(object.getString("name"));
                 }catch(JSONException e){
                     e.printStackTrace();
                 }
                 try{
                     user.setEmail(object.getString("email"));
                 }catch(JSONException e){
                     e.printStackTrace();
                 }
                 user.saveInBackground(new SaveCallback() {
                     @Override
                     public void done(ParseException e) {
                         alertDisplayer("First Time Login", "Welcome!");
                     }
                 });
             }
         });
         Bundle parameters = new Bundle();
         parameters.putString("fields","name,email");
         request.setParameters(parameters);
         request.executeAsync();
     }
    
  5. It’s interesting to add an additional method to display Alert Dialogs and make the process look more professional. The method below does this:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private void alertDisplayer(String title,String message){
         AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this)
                 .setTitle(title)
                 .setMessage(message)
                 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         dialog.cancel();
                         // don't forget to change the line below with the names of your Activities
                         Intent intent = new Intent(LoginActivity.this, LogoutActivity.class);
                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                         startActivity(intent);
                     }
                 });
         AlertDialog ok = builder.create();
         ok.show();
     }
    

Step 6 - Log out

  1. Import into your LogoutActivity, in addition to the dependencies imported in Step 4:
    1
    2
    // Facebook main dependencies
    import com.facebook.login.LoginManager;
    
  2. To implement Facebook Logout, simply use the code mentioned below:
    1
    2
    3
    4
    5
    // logging out of Facebook
    LoginManager.getInstance().logOut();
    // logging out of Parse
    ParseUser.logOut();
    alertDisplayer("So, you're going...", "Ok...Bye-bye then");
    

    In the example project, this code is placed inside a LOG OUT button callback.

    The method alertDisplayer is the same that you added in the LoginActivity, don’t forget to change its Intent arguments though.

It’s done!

At this stage, you can log in, register and log out of your app with Facebook using Parse Server core features through Back4App!