Facebook Login in Android with Firebase Authentication (2026)
Last Updated: | Author: Deep Singh
Facebook Login is one of the most popular ways for users to sign into Android apps. Instead of creating a new account and remembering another password, they tap one button and they're in.
In this tutorial, you'll integrate the Facebook SDK with Firebase Authentication in Android. We'll set up the Facebook app, wire up the SDK in your Android project, and build a login flow that hands off the Facebook access token to Firebase for verification.
Output Screen
The app shows a standard "Continue with Facebook" button. After the user authorizes the app, they're signed into Firebase and taken to a home page that shows their profile picture and email.
Creating a Facebook App
Before writing any code, you need a Facebook app to get an App ID. Here's what to do:
- Go to Facebook Developers and create a new app of type Consumer.
- Add the Facebook Login product to your app.
- Under Facebook Login → Settings, add your Android package name and the Key Hash (SHA-1 fingerprint).
- Enable Client OAuth Login and Web OAuth Login.
- Copy your App ID — you'll need it shortly.
To generate your Key Hash, run this in your terminal:
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
Paste the resulting base64 string into Facebook's "Key Hashes" field.
Configuring Firebase
In the Firebase Console, enable Facebook as a sign-in provider:
- Go to Authentication → Sign-in method.
- Enable Facebook.
- Paste your Facebook App ID and App Secret (found in Facebook Developer Console → Settings → Basic).
- Copy the OAuth redirect URI Firebase gives you and paste it into Facebook Login → Settings → Valid OAuth Redirect URIs.
Register your Android app in Firebase with the package name and SHA-1, then download google-services.json and place it in app/.
Gradle Dependencies
In your app-level build.gradle, add the following dependencies:
dependencies {
// Use the Firebase BoM so all Firebase libraries align
implementation platform('com.google.firebase:firebase-bom:33.5.1')
implementation 'com.google.firebase:firebase-auth'
// Facebook SDK
implementation 'com.facebook.android:facebook-android-sdk:17.0.0'
// Glide for loading the profile picture from a URL
implementation 'com.github.bumptech.glide:glide:4.16.0'
// ConstraintLayout
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}
And at the bottom of the file:
apply plugin: 'com.google.gms.google-services'
What's changed from the original:
firebase-auth:19.3.2is outdated. Use the Firebase BoM (33.5.1) so all Firebase artifacts stay in sync.glide:4.8.0is from 2018 and incompatible with modern Android Gradle Plugin. Updated to4.16.0.- The
annotationProcessorline for Glide is only needed if you use Glide's generated API. For simpleGlide.with().load().into()calls, you don't need it. - Facebook SDK updated from
[5,6)(which is 2018-era) to17.0.0.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfbintegration">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".HomePage" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<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>
</application>
</manifest>
What's fixed: The original used <uses-permission-sdk-23> for INTERNET, which is wrong. INTERNET is a normal permission granted at install time — it uses a plain <uses-permission> tag. Also added android:exported="true" on CustomTabActivity, which is required for Android 12+ (API 31+) since the activity has an intent-filter.
strings.xml
<resources>
<string name="app_name">MyFBIntegration</string>
<!-- Replace with your actual Facebook App ID -->
<string name="facebook_app_id">YOUR_FACEBOOK_APP_ID</string>
<!-- This is "fb" + your App ID -->
<string name="fb_login_protocol_scheme">fbYOUR_FACEBOOK_APP_ID</string>
</resources>
Critical fix: The original had a mismatched App ID in the two string values — 733541494133893 for facebook_app_id but fb733441494133793 for the protocol scheme. The digits didn't match! The scheme must always be fb followed by the exact same App ID. A mismatch here causes silent login failures. I've replaced both with placeholders so you don't ship a broken login flow.
Layouts
activity_main.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.facebook.login.widget.LoginButton
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
What's fixed: The original had layout_gravity (which does nothing in ConstraintLayout) and used bias values that made the button sit awkwardly near the top. Now it's properly centered.
activity_home_page.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="20dp">
<ImageView
android:id="@+id/myimage"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/mydetail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:textSize="18sp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:onClick="logout"
android:text="Logout" />
</LinearLayout>
MainActivity.java
package com.example.myfbintegration;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "FacebookLogin";
private static final String EMAIL = "email";
private LoginButton loginButton;
private CallbackManager callbackManager;
private FirebaseAuth mAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
loginButton = findViewById(R.id.login_button);
loginButton.setPermissions(Arrays.asList(EMAIL));
callbackManager = CallbackManager.Factory.create();
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Log.d(TAG, "Facebook login success");
handleFacebookAccessToken(loginResult.getAccessToken());
}
@Override
public void onCancel() {
Log.d(TAG, "Facebook login cancelled");
}
@Override
public void onError(@NonNull FacebookException exception) {
Log.e(TAG, "Facebook login error", exception);
Toast.makeText(MainActivity.this,
"Facebook login failed: " + exception.getMessage(),
Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onStart() {
super.onStart();
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
goToHomePage();
}
}
private void handleFacebookAccessToken(AccessToken token) {
Log.d(TAG, "Exchanging Facebook token for Firebase credential");
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
Log.d(TAG, "Firebase sign-in with Facebook succeeded");
goToHomePage();
} else {
Log.e(TAG, "Firebase sign-in failed", task.getException());
Toast.makeText(MainActivity.this,
"Firebase sign-in failed: " + task.getException(),
Toast.LENGTH_LONG).show();
}
});
}
private void goToHomePage() {
startActivity(new Intent(MainActivity.this, HomePage.class));
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Pass the result to the Facebook SDK first (it must be called before super)
callbackManager.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
}
What's fixed:
- Removed unused imports (
PackageInfo,PackageManager,Signature,Base64,MessageDigest,NoSuchAlgorithmException,FacebookSdk,AppEventsLogger). The original imported all of these but only used a few. - Removed the
onActivityResultordering issue — the Facebook SDK requires its handler to be called beforesuper, which the original did correctly, but I've added a comment explaining why. - Replaced all
Log.ecalls for informational messages withLog.d, keptLog.eonly for real errors. - Added error handling with Toast messages so users see what went wrong.
- Renamed
facebookHandlerCodeto the more descriptivehandleFacebookAccessToken. - Added a
TAGconstant for cleaner logging. - Removed the `loginButton.setVisibility(View.INVISIBLE)` call, which was unnecessary since we navigate away immediately.
HomePage.java
package com.example.myfbintegration;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public class HomePage extends AppCompatActivity {
private FirebaseAuth mAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
mAuth = FirebaseAuth.getInstance();
ImageView image = findViewById(R.id.myimage);
TextView detail = findViewById(R.id.mydetail);
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
Glide.with(this).load(user.getPhotoUrl()).into(image);
String email = user.getEmail() != null ? user.getEmail() : "No email";
detail.setText(email);
}
}
public void logout(View view) {
mAuth.signOut();
startActivity(new Intent(this, MainActivity.class));
finish();
}
}
What's fixed: Added a null check on user.getEmail() so the app doesn't show the literal string "null" if the email is missing. Also cleaned up indentation and removed the redundant empty lines.
How the Login Flow Works
Here's the full sequence of events when a user taps "Continue with Facebook":
- Facebook SDK opens the Facebook app (or a web view if the app isn't installed) and asks the user to authorize your app.
- The user grants permission, and Facebook calls back into your app with a
LoginResultcontaining anAccessToken. - Your
onSuccesscallback fires, and you pass the token tohandleFacebookAccessToken(). - You create a Firebase
AuthCredentialusingFacebookAuthProvider.getCredential(token.getToken()). - Firebase verifies the token with Facebook. If it's valid, Firebase creates (or retrieves) a user account and returns a
FirebaseUser. - You navigate to the home page and display the user's Facebook profile picture and email.
The Facebook SDK handles the OAuth dance. Firebase handles identity verification. Your app only needs to coordinate the handoff.
Common Pitfalls
- Mismatched App ID in strings.xml. The
fb_login_protocol_schememust be exactlyfb+ your App ID, with every digit matching. A single typo causes silent login failures that are hard to debug. - Missing Key Hash. Facebook requires your app's SHA-1 to be registered as a Key Hash in the Facebook Developer Console. Without it, login fails with "Invalid key hash".
- Wrong permissions. Facebook SDK v5+ requires you to explicitly request permissions with
setPermissions(). If you don't, you won't get the user's email. - Not calling
callbackManager.onActivityResult(). The Facebook SDK needs to receive the login result. If you forget this line, the login callback never fires. - Calling
super.onActivityResult()before the callback manager. The Facebook SDK must be the first to receive the result. Reverse the order and you'll get silent failures. - Using an old Facebook SDK. The
[5,6)version range from old tutorials is deprecated. Use the latest stable version. - Firebase Facebook provider not enabled. If you forget to enable Facebook in Firebase Authentication → Sign-in method,
signInWithCredentialwill fail with an error. - OAuth redirect URI not configured. Firebase gives you a redirect URI that you must paste into Facebook Login Settings → Valid OAuth Redirect URIs. Skipping this step breaks the login.
- SHA-1 mismatch between Firebase and Facebook. Both Firebase and Facebook need your app's SHA-1 registered. If one is missing or wrong, login fails silently.
- Using
uses-permission-sdk-23for INTERNET. That tag is only for runtime permissions. INTERNET is granted at install time and uses plainuses-permission.
Wrapping Up
You now have a working Facebook Login flow with Firebase Authentication in Android. Users tap one button, authorize your app with Facebook, and they're signed into Firebase automatically. The home page displays their Facebook profile picture and email.
From here, you can extend the app with:
- Additional sign-in providers. Combine Facebook Login with Google Sign-In and email/password for a complete auth system.
- Firestore user profiles. Store extra user data (display name, preferences) in Firestore, linked by the Firebase UID.
- Account linking. Let users link their Facebook account to an existing email-based account.
- Limited Login on iOS 14.5+. Apple's App Tracking Transparency requires limited login for certain tracking scenarios on iOS.
- Error handling improvements. Show specific error messages for common failures like missing permissions or expired tokens.
No comments:
Post a Comment