Last updated: February 2026
React Native: 0.82.x (New Architecture)
Library:react-native-fbsdk-nextv13.x
Facebook SDK: iOS 18.x / Android 18.x
This guide walks you through integrating Facebook Login into a modern React Native app using react-native-fbsdk-next. It covers everything from Facebook Developer Console setup to production-ready TypeScript code.
- Prerequisites
- Facebook Developer Console Setup
- Install the Library
- Android Configuration
- iOS Configuration
- React Native Code (TypeScript)
- Backend Integration
- Troubleshooting
- Common Pitfalls
Before starting, make sure you have:
- React Native 0.82+ project (with New Architecture / Fabric enabled)
- A Facebook Developer Account at developers.facebook.com
- Xcode 16+ (for iOS)
- Android Studio with SDK 24+ (for Android)
- CocoaPods installed (
gem install cocoapods)
- Go to Facebook Developer Console
- Click Create App β Choose Consumer or Business type
- Enter your app name and contact email
- Once created, note down your:
- App ID (e.g.,
XXXXXXXXXXXXXXXXX) - Client Token (found under Settings β Advanced β Client Token, e.g.,
XXXXXXXXXXXXXXXXXXXXXXXXXX)
- App ID (e.g.,
- In your Facebook app dashboard, click Add Product
- Select Facebook Login β Set Up
- Enable Client OAuth Login and Web OAuth Login
- Add valid OAuth redirect URIs if using a backend flow
- Go to Settings β Basic β Add Platform β Android
- Enter your Package Name (e.g.,
com.example.myapp) - Enter your Key Hash β generate it with:
# Debug key hash
keytool -exportcert -alias androiddebugkey \
-keystore ~/.android/debug.keystore \
| openssl sha1 -binary | openssl base64
# Release key hash (replace with your keystore path)
keytool -exportcert -alias your-alias \
-keystore /path/to/your-release-key.keystore \
| openssl sha1 -binary | openssl base64- Enable Single Sign On
- Go to Settings β Basic β Add Platform β iOS
- Enter your Bundle ID (e.g.,
com.example.myapp) - Enable Single Sign On
npm install react-native-fbsdk-nextcd ios && pod install && cd ..Note: With React Native 0.82+, autolinking handles the native module registration automatically. No manual linking is needed.
You need to edit 3 files in the android/ directory.
Add your Facebook App ID and Client Token as string resources:
<resources>
<string name="app_name">YourAppName</string>
<string name="facebook_app_id">YOUR_FACEBOOK_APP_ID</string>
<string name="facebook_client_token">YOUR_FACEBOOK_CLIENT_TOKEN</string>
</resources>Example:
<resources>
<string name="app_name">MyApp</string>
<string name="facebook_app_id">XXXXXXXXXXXXXXXXX</string>
<string name="facebook_client_token">XXXXXXXXXXXXXXXXXXXXXXXXXX</string>
</resources>Add Facebook meta-data and the content provider inside the <application> tag:
<application ...>
<!-- Facebook SDK Configuration -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="@string/facebook_client_token" />
<provider
android:authorities="com.facebook.app.FacebookContentProviderYOUR_FACEBOOK_APP_ID"
android:name="com.facebook.FacebookContentProvider"
android:exported="true" />
<!-- /Facebook SDK Configuration -->
<activity
android:name=".MainActivity"
... >
...
</activity>
</application>
β οΈ Critical: TheFacebookContentProviderauthority must end with your actual Facebook App ID. This is the #1 source of Android crashes:<!-- β CORRECT β App ID matches strings.xml --> android:authorities="com.facebook.app.FacebookContentProviderXXXXXXXXXXXXXXXXX" <!-- β WRONG β hardcoded old/different App ID --> android:authorities="com.facebook.app.FacebookContentProviderYYYYYYYYYYYYYYYYY"
Ensure this permission exists in AndroidManifest.xml (usually already present):
<uses-permission android:name="android.permission.INTERNET" />That's it for Android. The Facebook SDK auto-initializes on Android β no Application class changes needed with react-native-fbsdk-next v13+.
You need to edit 2 files in the ios/ directory.
Add the following keys inside the top-level <dict>:
<!-- ============ Facebook SDK ============ -->
<key>FacebookAppID</key>
<string>YOUR_FACEBOOK_APP_ID</string>
<key>FacebookClientToken</key>
<string>YOUR_FACEBOOK_CLIENT_TOKEN</string>
<key>FacebookDisplayName</key>
<string>Your App Name</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
<!-- ============ /Facebook SDK ============ -->Then, add a Facebook URL scheme to CFBundleURLTypes. If you already have a CFBundleURLTypes entry (e.g., for Google Sign-In), just add a new <dict> entry alongside it:
<key>CFBundleURLTypes</key>
<array>
<!-- Existing entry (e.g., Google Sign-In) -->
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.YOUR_GOOGLE_CLIENT_ID</string>
</array>
</dict>
<!-- Facebook URL Scheme (REQUIRED) -->
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fbYOUR_FACEBOOK_APP_ID</string>
</array>
</dict>
</array>
β οΈ Critical: The URL scheme must befbfollowed by your App ID with no spaces or dashes:
fbXXXXXXXXXXXXXXXXXβ
fb-XXXXXXXXXXXXXXXXXβ
XXXXXXXXXXXXXXXXXβ
Full Info.plist Example:
<!-- Facebook SDK -->
<key>FacebookAppID</key>
<string>XXXXXXXXXXXXXXXXX</string>
<key>FacebookClientToken</key>
<string>XXXXXXXXXXXXXXXXXXXXXXXXXX</string>
<key>FacebookDisplayName</key>
<string>MyApp</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
<!-- /Facebook SDK -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fbXXXXXXXXXXXXXXXXX</string>
</array>
</dict>
</array>This is the most commonly missed step and the #1 cause of iOS crashes. The Facebook SDK must be initialized in AppDelegate and URL scheme handling must be added.
React Native 0.82 uses a new AppDelegate structure with RCTReactNativeFactory. Here is the complete working AppDelegate.swift:
import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import FBSDKCoreKit // β ADD THIS IMPORT
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var reactNativeDelegate: ReactNativeDelegate?
var reactNativeFactory: RCTReactNativeFactory?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = RCTReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
window = UIWindow(frame: UIScreen.main.bounds)
factory.startReactNative(
withModuleName: "YourAppName",
in: window,
launchOptions: launchOptions
)
// β
Initialize Facebook SDK
ApplicationDelegate.shared.application(
application,
didFinishLaunchingWithOptions: launchOptions
)
return true
}
// β
Handle Facebook URL scheme redirects
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return ApplicationDelegate.shared.application(
app,
open: url,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplication.OpenURLOptionsKey.annotation]
)
}
}
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
override func sourceURL(for bridge: RCTBridge) -> URL? {
self.bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}Key additions:
import FBSDKCoreKitat the topApplicationDelegate.shared.application(...)call indidFinishLaunchingWithOptionsapplication(_:open:options:)method to handle thefb{appId}://URL redirect
π‘ Why is this needed? When the user taps "Continue" in the Facebook login dialog, Facebook redirects back to your app using the
fb{appId}://URL scheme. Without theapplication(_:open:options:)handler, iOS doesn't know what to do with this redirect and the app crashes.
If you're on an older React Native version using Objective-C, add:
// AppDelegate.mm
#import <FBSDKCoreKit/FBSDKCoreKit-Swift.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ... existing code ...
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [[FBSDKApplicationDelegate sharedInstance] application:app
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}import { LoginManager, AccessToken } from 'react-native-fbsdk-next';
import { Alert } from 'react-native';
const loginWithFacebook = async (): Promise<string | null> => {
try {
// Request permissions
const result = await LoginManager.logInWithPermissions([
'public_profile',
'email',
]);
if (result.isCancelled) {
console.log('Facebook login cancelled');
return null;
}
// Get the access token
const data = await AccessToken.getCurrentAccessToken();
if (!data) {
throw new Error('Failed to get access token');
}
console.log('Facebook access token:', data.accessToken.toString());
return data.accessToken.toString();
} catch (error) {
console.error('Facebook login error:', error);
Alert.alert('Login Failed', (error as Error).message);
return null;
}
};Here's how to integrate it into an AuthContext β the pattern used in production apps:
// context/AuthContext.tsx
import React, { createContext, useContext, useState } from 'react';
import { Alert } from 'react-native';
import { LoginManager, AccessToken } from 'react-native-fbsdk-next';
interface User {
id: number;
name: string;
email: string;
}
interface AuthContextType {
user: User | null;
isLoading: boolean;
loginWithFacebook: () => Promise<void>;
logout: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(false);
const loginWithFacebook = async (): Promise<void> => {
try {
setIsLoading(true);
// Step 1: Open Facebook Login dialog
const result = await LoginManager.logInWithPermissions([
'public_profile',
'email',
]);
if (result.isCancelled) {
throw new Error('Login cancelled');
}
// Step 2: Get the access token
const tokenData = await AccessToken.getCurrentAccessToken();
if (!tokenData) {
throw new Error('Failed to obtain access token');
}
const accessToken = tokenData.accessToken.toString();
console.log('β
Facebook login success:', accessToken);
// Step 3: Send token to your backend for verification
const response = await fetch('https://your-api.com/auth/login/facebook', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ accessToken }),
});
if (!response.ok) {
const errorBody = await response.json();
throw new Error(errorBody.message || 'Server authentication failed');
}
const authData = await response.json();
setUser(authData.user);
} catch (error) {
console.error('Facebook login error:', error);
Alert.alert('Facebook Login Failed', (error as Error).message);
} finally {
setIsLoading(false);
}
};
const logout = async (): Promise<void> => {
LoginManager.logOut();
setUser(null);
};
return (
<AuthContext.Provider
value={{ user, isLoading, loginWithFacebook, logout }}
>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};// components/FacebookLoginButton.tsx
import React from 'react';
import {
TouchableOpacity,
Text,
ActivityIndicator,
StyleSheet,
} from 'react-native';
import { useAuth } from '../context/AuthContext';
const FacebookLoginButton: React.FC = () => {
const { loginWithFacebook, isLoading } = useAuth();
return (
<TouchableOpacity
style={styles.button}
onPress={loginWithFacebook}
disabled={isLoading}
activeOpacity={0.8}
>
{isLoading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.text}>Continue with Facebook</Text>
)}
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
button: {
backgroundColor: '#1877F2',
paddingVertical: 14,
paddingHorizontal: 24,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
gap: 8,
},
text: {
color: '#fff',
fontSize: 16,
fontWeight: '700',
},
});
export default FacebookLoginButton;import { Profile } from 'react-native-fbsdk-next';
const getFacebookProfile = async () => {
const currentProfile = await Profile.getCurrentProfile();
if (currentProfile) {
console.log('Name:', currentProfile.name);
console.log('First Name:', currentProfile.firstName);
console.log('Last Name:', currentProfile.lastName);
console.log('Profile Image:', currentProfile.imageURL);
console.log('User ID:', currentProfile.userID);
}
};Your backend should:
- Receive the Facebook access token from the mobile app
- Verify the token with Facebook's Graph API
- Create or find the user in your database
- Return your own JWT/session token
// POST /auth/login/facebook
app.post('/auth/login/facebook', async (req, res) => {
const { accessToken } = req.body;
// Verify with Facebook Graph API
const fbResponse = await fetch(
`https://graph.facebook.com/me?fields=id,name,email,picture&access_token=${accessToken}`,
);
if (!fbResponse.ok) {
return res.status(401).json({ message: 'Invalid Facebook token' });
}
const fbUser = await fbResponse.json();
// Find or create user in your database
let user = await User.findOne({ where: { facebookId: fbUser.id } });
if (!user) {
user = await User.create({
facebookId: fbUser.id,
name: fbUser.name,
email: fbUser.email,
avatar: fbUser.picture?.data?.url,
});
}
// Generate your own auth token
const token = generateJWT(user);
return res.json({ user, token });
});Cause: Missing FBSDKCoreKit initialization in AppDelegate.swift.
Fix: Add import FBSDKCoreKit and the two ApplicationDelegate.shared.application(...) calls as shown in Section 5.2.
Cause: The android:authorities value in AndroidManifest.xml doesn't match your actual Facebook App ID.
Fix: Ensure the authority is com.facebook.app.FacebookContentProvider + your exact App ID from strings.xml.
Cause: Missing application(_:open:options:) URL handler in AppDelegate.swift.
Fix: Add the URL scheme handler method as shown in Section 5.2.
Possible causes:
- Facebook App is in Development Mode and the test user isn't added
- The Facebook App ID in
Info.plist/strings.xmldoesn't match the Console - On iOS simulator: Facebook app isn't installed, so it uses Safari β ensure
LSApplicationQueriesSchemesis defined
Fix: Generate the correct key hash and add it to your Facebook Developer Console:
# Debug
keytool -exportcert -alias androiddebugkey \
-keystore ~/.android/debug.keystore \
| openssl sha1 -binary | openssl base64
# Default password: androidFix:
cd ios
pod deintegrate
pod install
cd ..Then clean the Xcode build:
cd ios
xcodebuild clean -workspace YourApp.xcworkspace -scheme YourApp
cd ..| # | Pitfall | Platform | Impact |
|---|---|---|---|
| 1 | Missing import FBSDKCoreKit + SDK init in AppDelegate.swift |
iOS | App crash |
| 2 | Missing application(_:open:options:) URL handler |
iOS | Login silently fails |
| 3 | Wrong App ID in FacebookContentProvider authority |
Android | App crash |
| 4 | Missing FacebookAppID / FacebookClientToken in Info.plist |
iOS | App crash |
| 5 | Missing fb{appId} URL scheme in CFBundleURLTypes |
iOS | Login redirect fails |
| 6 | Facebook App in Development Mode without test users | Both | Login rejected |
| 7 | Missing key hash in Facebook Developer Console | Android | "Invalid key hash" error |
| 8 | Using fb-{appId} instead of fb{appId} (no hyphen) |
iOS | URL scheme mismatch |
Before shipping, verify:
-
react-native-fbsdk-nextinstalled and pods installed - Android:
facebook_app_idandfacebook_client_tokeninstrings.xml - Android:
meta-dataentries inAndroidManifest.xml - Android:
FacebookContentProviderauthority matches your App ID - Android: Key hash added to Facebook Developer Console
- iOS:
FacebookAppID,FacebookClientToken,FacebookDisplayNameinInfo.plist - iOS:
fb{appId}URL scheme inCFBundleURLTypes - iOS:
LSApplicationQueriesSchemesincludesfbapiandfb-messenger-share-api - iOS:
import FBSDKCoreKitinAppDelegate.swift - iOS:
ApplicationDelegate.shared.application(...)called indidFinishLaunchingWithOptions - iOS:
application(_:open:options:)URL handler method added - Console: Facebook App is in Live mode (or test users are added for Development)
- Console: iOS Bundle ID and Android Package Name are registered
| Library | Version | Notes |
|---|---|---|
react-native |
0.82.x | New Architecture (Fabric) supported |
react-native-fbsdk-next |
13.x | Auto-linking, no manual linking needed |
| Facebook iOS SDK | 18.x | Managed via CocoaPods |
| Facebook Android SDK | 18.x | Managed via Gradle (auto) |
| Xcode | 16+ | Required for RN 0.82 |
| Android SDK | 24+ (minSdk) | Required for FBSDK 18 |
Written based on real-world production debugging. The most common crash cause on iOS is the missing AppDelegate.swift setup, which is poorly documented in the official react-native-fbsdk-next README for React Native 0.82+.