How to connect Facebook Auth to React Native App in 3 easy steps

Posted by Vira Rodionova (React Native Developer) on 2019-05-17

Hi! This post describes Facebook’s authentication process in a React Native mobile application.

The purposes of this post are: providing a step-by-step tutorial about Facebook authentication connection to the React Native application, a description of the process of interacting with the server, some of the pitfalls on the way and my groundwork about the case.

However, before starting, let’s consider a diagram of the mobile application interaction with Facebook services. It will allow us to understand why we perform particular actions.

facebook-with-mobile-app.png

The sequence of interaction is as follows:

  1. A user initiates the action that is associated with Facebook services (in the post we will have authentication)
  2. The mobile application sends a request to Facebook services to perform an action. The following data is attached to the request:
    1. the type of action to be performed
    2. APP ID, which corresponds to the Facebook application ID
    3. ID of the source code of the React Native application (packageName / bundleId for Android / iOS, respectively)
  3. Facebook verifies the request with a pair of values: APP ID, packageName / bundleId
  4. After successful verification, Facebook processes the requested action.
  5. And Facebook returns to the mobile application response with the result.

A brief description of the authentication setup process

To configure our application, you must perform the following sequence of actions:

  1. Setting up the application on Facebook
    1. Create a Facebook Developer Account
    2. Create a Facebook application
    3. Register platforms on Facebook
  2. Configuring React Native Applications
    1. [Android] Connecting Facebook SDK and setting up Facebook APP ID in app code
    2. [iOS] Connecting Facebook SDK and setting up Facebook APP ID in app code
  3. Configuring Facebook Login
    1. Connecting Facebook Login product
    2. Advanced settings for Android
    3. An example of getting a token through the Login Manager

1. Setting up the application on Facebook

To use the “products” provided by Facebook, for example, authorization, advertising, in-app purchases etc. - you need to create an application in “Facebook for Developers”. After creating the application, you will receive a unique ID, which is required to identify your React Native application on Facebook.

1.1. Create a Facebook Developer Account

You need to have a Facebook account to create applications on “Facebook for developers”. You can use your personal one, but I advise you to register a separate one. By default, “Facebook for developers” is available for all accounts. So, you can start creating an application.

1.2. Create a Facebook app

  • Go to Facebook Dashboard page and click on the Add a New App button.
  • In the window that appears, enter the required information and click on the Create App ID button.
  • Facebook will ask you to choose a usage scenario, but we can skip this step.

Now we have an APP ID for your React Native application to access Facebook.

APP ID

1.3. Register platforms on Facebook

Also, Facebook must know about those applications that can access it. Therefore, in the settings of the Facebook application, you should also specify the ID of your React Native application. Facebook works directly with native applications, so you need to register an ID for each platform. It ensures the uniqueness of the application that wants to use Facebook services. Application distribution platforms (Play Market / AppStore) do not allow the appearance of two applications with identical identifiers (packageName / bundleId).

To add a platform, open the Facebook App Settings -> Basic and find the “Add platform” button at the bottom of the page:

Facebook platforms: Android

Facebook platforms: iOS

When the application is created in the AppStore, you will need to update the field: iPhone Store ID

How to find Android packageName

/app/src/main/AndroidManifest.xml

1
<manifest package="com.reactnativeads" ...>

How to find iOS bundleId

bundle-id.png

2. Configuring React Native Applications

The first thing you need to connect to the React Native application if you decide to use Facebook services is the Facebook SDK. You should also “register” the APP ID, which we received in step 1.2, in the configuration files for each platform.

To interact with the Facebook SDK, there is a react-native-fbsdk library in React Native.

You can install it by running the command in the terminal:

1
yarn add react-native-fbsdk

or

1
npm install --save react-native-fbsdk

Instructions for further connection can be found in the documentation for the library. BUT:

!!DO NOT USE react-native link react-native-fbsdk !!

I am an adherent of manual linking libraries in React Native. So I do not recommend using the react-native link. Since using link scripts, I can never be 100% sure that my project will start and these scripts will not break anything. Moreover, manual linking is a simple operation and is usually well described in the documentation for libraries using native modules.
For example, for iOS, there is a description of the manual linking process for all libraries in the general case in React Native official documentation.

2.1. [Android] Connecting Facebook SDK and setting up Facebook APP ID

In the case of the react-native-fbsdk library, the manual linking process is described in the configuration section. Following these instructions, you can easily link the library.

Setting up a Facebook APP ID in Android application

This configuration is described in the Facebook documentation, and there are links to the necessary pages in react-native-fbsdk. However, you do not need to do everything described here. Here is the “extract” from the React Native documentation.

From the official documentation, we need to perform only the Add Facebook App ID step:

In Android, we need to add the Facebook APP ID to the Android manifest. Perform the next:

  • Open /app/src/main/res/values/strings.xml file
  • Add the following line:

    1
    <string name="facebook_app_id">Facebook App ID</string>
  • Open /app/src/main/AndroidManifest.xml

  • Add a line with meta-data to the element application::
    1
    2
    3
    4
    5
    <application android:label="@string/app_name" ...>
    ...
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
    ...
    </application>

2.2. [iOS] Connecting Facebook SDK and setting up Facebook APP ID

Unfortunately, there is no description of manual linking in the documentation of the react-native-fbsdk library so that I will describe it here:

1. Download Facebook SDK

If you are setting up a Facebook SDK for iOS for the first time on your machine, make sure that you download the latest Facebook SDK from here (the ‘Download’ section) with the archive and unpack it into the ~/Documents/FacebookSDK folder

It should contain something like this:

finder-facebook-sdk

2. Link the native project

link-facebook-sdk-1

link-facebook-sdk-2

link-facebook-sdk-3

Add to PROJECT_NAME -> TARGETS -> PROJECT_NAME -> Build Settings -> Framework Search Paths the path to the Facebook SDK: $(HOME)/Documents/FacebookSDK/

framework-search-paths

Add frameworks: FBSDKCoreKit.framework, FBSDKLoginKit.framework and FBSDKShareKit.framework to Link Binary With Libraries:

link-facebook-sdk-4

The most frequent problems

  1. Once again: if you are setting up a Facebook SDK for iOS for the first time on your machine, make sure that you download the latest Facebook SDK from here (the ‘Download’ section) with the archive and unpack it into the ~/Documents/FacebookSDK folder.
  2. Also, be sure to add the path $(HOME)/Documents/FacebookSDK/ to PROJECT_NAME -> TARGETS -> PROJECT_NAME -> Build Settings -> Framework Search Paths (see screenshot above).
  3. If the error FBSDKShareKit/FBSDKShareKit.h not found appeared, and you have completed the previous paragraph, then this can be solved in two ways: 1 or 2. The second one was helpful for me.
  4. If you are using Xcode 10 and received an error: Cycle in dependencies between targets, check this
  5. Before making the build with the changes, do Product -> Clean

If these solutions did not help you, look in the troubleshooting section of react-native-fbsdk.

3. Register Facebook APP ID in iOS application

From the official documentation, we need to perform only the steps Configure Info.plist and Connect App Delegate:

  • Open /ios/ProjectName/Info.plist and add the lines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb{your-app-id}</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>{your-app-id}</string>
<key>FacebookDisplayName</key>
<string>{your-app-name}</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
  • Replace {your-app-id}, and {your-app-name} with your app’s App’s ID and name found on the Facebook App Dashboard.

app-id-app-name

  • Open /ios/ProjectName/AppDelegate.m and add the lines:
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
//  AppDelegate.m
#import <FBSDKCoreKit/FBSDKCoreKit.h>

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// You can skip this line if you have the latest version of the SDK installed
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
// Add any custom logic here.
return YES;
}

- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {

BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
// Add any custom logic here.
return handled;
}

So, Facebook SDK configuration is completed, and you can start embedding various services in your application.

3. Authorization in the application through Facebook

To begin, I propose to consider the scheme of the authorization process in the application with own backend using Facebook authentication.

facebook-auth.png

  1. A user initiates an action
  2. The application sends a request for authentication to Facebook
  3. The user enters his data and, in the case of successful authentication, Facebook returns Facebook Token to our application.
  4. Next, we try to log in to our application and send Facebook Token to the backend for a specific route.
  5. Backend verifies the Facebook Token we sent.
  6. Backend performs authorization (registration or login)
  7. Backend returns us AuthToken for our system.

Authorization setup through Facebook is well described in the official documentation for React Native.

3.1. Connecting Facebook Login product

I indicate this step here to remind you that we need to connect the Facebook Login product to the Facebook console.

add-facebook-product.png

3.2. Advanced settings for Android

To make Facebook Login working in your React Native application, you need to make several more settings.

1) Add lines to /app/src/main/res/values/strings.xml:

1
2
<string name="fb_login_protocol_scheme">fb{your-app-id}</string>
<string name="facebook_app_name">{your-app-name}</string>

2) And a couple of lines more in /app/src/main/AndroidManifest.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<application>
...

<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/facebook_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>

3) Also, you need to register Key Hashes in the platform settings in Facebook Settings. You need to register the keys for debugging as well as for release versions.

As written in the official Facebook documentation:

Facebook uses the key hash to authenticate interactions between your app and the Facebook app. If you run apps that use Facebook Login, you need to add your Android development key hash to your Facebook developer profile.

[MacOS]: To get Key Hash for development builds, you need to run this command with the password “android“:

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

Read more about Key Hashes here.

!!N.B.: to run applications on Android, you also need to register Key Hashes for the debug and release versions

3.3. An example of getting a token through the Login Manager

File sessionUtils.js

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
29
30
31
32
33
34
35
import FBSDK from 'react-native-fbsdk';

const { LoginManager, AccessToken } = FBSDK;

const PERMISSIONS = [ 'public_profile', 'email' ];

export async function getTokenFacebook() {
const currentAccessToken = await AccessToken.getCurrentAccessToken();

if (currentAccessToken) {
return currentAccessToken.accessToken;
}

const logInResponse = await LoginManager.logInWithReadPermissions(PERMISSIONS);

if (!logInResponse.isCancelled) {
const accessTokenObject = await AccessToken.getCurrentAccessToken();

return accessTokenObject.accessToken;
}

throw new Error('Cancelled');
}

export async function logOutFacebook() {
// async emulation
return new Promise((resolve, reject) => {
try {
LoginManager.logOut();
setTimeout(resolve, 400);
} catch (error) {
reject(error);
}
});
}

File App.js

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import React, { Component} from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';

import { getTokenFacebook, logOutFacebook } from './utils/sessionUtils.js';

export default class App extends Component {
state = {
token : null,
error : null
};

handleLoginButtonPressed = async () => {
try {
await logOutFacebook();
const token = await getTokenFacebook();
this.setState({ token, error: null });
} catch(error) {
this.setState({ error: error.message });
}
}

handleLogoutButtonPressed = async () => {
try {
await logOutFacebook();
this.setState({ token: null, error: null });
} catch(error) {
this.setState({ error: error.message });
}
}

render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Facebook Auth Token</Text>
<Text style={styles.instructions}>{this.state.error || this.state.token}</Text>
<View style={styles.buttonsContainer}>
<Button title='Login' onPress={this.handleLoginButtonPressed} />
<Button title='Logout' onPress={this.handleLogoutButtonPressed} />
</View>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
buttonsContainer : {
margin : 5,
minHeight : 80,
justifyContent : 'space-between'
}
});

Results: Android/iOS


result-android.gif result-ios.gif

Conclusions

This post described the detailed process of connecting the Facebook SDK and Facebook Login to your React Native application. In general, integration consists of the following components:

  • Facebook
    • creating an application
    • adding platforms
    • [Android] add key hashes
    • add product Facebook Login
  • React Native
    • installing the Facebook SDK to the application
    • adding Facebook APP ID to Info.plist and AndroidManifest.xml
    • configuring Android application (AndroidManifest.xml)
    • using Facebook SDK features

The most painstaking work is to connect the Facebook SDK to the iOS application properly.

Also, I do not recommend using scripts for auto-linking libraries in React Native. Moreover, even for the library that is used to interact with the Facebook SDK, these scripts are not developed well.

The process of interaction with the Login Manager itself is described in several lines, that is good news :)

Good luck!

  • Facebook Developer Console Dashboard: link
  • Facebook Docs about React Native: link
  • react-native-fbsdk: link
  • iOS Facebook SDK: link
  • iOS manual linking: link
  • XCode 10 related issues: link, link
  • Android KeyHashes: link

Comments: