React Native Login Using the Facebook SDK
--
React Native has lot of dependencies, each depends on a tons of other dependencies, and they move pretty fast (and break things). Sometimes 2 frameworks get merged together, sometimes a framework get split into 2, which may cause breaking changes in your app. Although most of them are well known issues and can be solved with a couples of searches on Google. For me, React Native saves some time (at first) developing for both iOS and Android while taking me more time digging into issues and questions.
Depending on team preference and projects, React Native may be a consideration. In cases you need to build React Native apps with Facebook SDK, this post is for you. It shows how to implement Facebook SDK for a React Native apps that uses React Navigation and react-native-elements, together with my experiences about React Native.
As the time of this post, I use macOS 10.13.3
, Xcode 9.3
, Android Studio 3.1.4
, react-native-cli 2.0.1
, npm 6.3.0
, node 8.9.4
, nodenv 1.1.2
. I used to use yarn but now I find npm
works well so let’s stick with npm
.
I use Visual Studio Code as the editor, and the hot key that you need to remember the most is Shift + Option + F
, which is used to format code.
Create a React Native app
It is painful to setup environment and tools for React apps. Getting to know how to configure Webpack, Babel, Jest can take some time so people build a lot of boilerplate generator for this setup task.
I am familiar with this create-react-app so when I found create-react-native-app , which is also recommended in official React Native Getting Started guide, I give it a try immediately. In my experience, it seems like a quick way to play with React Native through Expo but comes with so many caveats. This approach will limit me in the long run although it has reject
to quit the playground mode.
Because you don’t build any native code when using Create React Native App to create a project, it’s not possible to include custom native modules beyond the React Native APIs and components that are available in the Expo client app.
I think they should rename the repo to create-react-native-expo-app
to avoid confusion. My little piece of advice when working with React Native, is because of its heavy dependencies, you should do a bit of research for every tools or frameworks that you like to add. The less dependencies, the better. There are many cases those stuff are unnecessary and you avoid having extra unneeded dependencies.
The official react-native init
works so well, for how to install this tool, visit Building Project with Native Code.
Running apps
To run iOS app, you should specify simulator
react-native run-ios — simulator=”iPhone X”
To run Android app, you should start emulator first, either via Android Studio or adb
, then react-native run-android
.
Install Facebook SDK
The Facebook SDK for React Native is quite straightforward to set up. Basically it is a wrapper around the native SDK for iOS and Android, so we need to use Xcode and Android Studio to configure some tasks. You also need to register an app on Facebook Developers page.
Firstly, install and link the react-native-fbsdk package
react-native install react-native-fbsdk
react-native link react-native-fbsdk
that gives you react-native-fbsdk”: “^.7.0
under dependencies
in your package.json
, meaning it integrates react-native-fbsdk
to iOS and Android.
Android Project: You can skip the build.gradle changes since that’s taken care of by the rnpm link step above
iOS Project: The react-native-fbsdk has been linked by rnpm
Setup for iOS
The react-native-fbsdk points us to Getting Started, but it is for native iOS apps !!!
You should instead follow Configure the Native iOS Project, as it has a script for setting up all things. Firstly, go to Quick Starts for how to change bundle id, configure Info.plist and add Track App Installs and App Opens
code. Note that the method didFinishLaunchingWithOptions
is already there in the react-native Xcode project, so you shouldn’t add new one.
How to change iOS project bundle id?
This is a pretty common question and people point to all sorts of scripts and frameworks to change just bundle id. You just need to open.xcproj
in ios
folder and change bundle id, like you with a normal native iOS project.
Then going back to Configure the Native iOS Project at step 7 to install and execute ios_setup.js
curl -O https://raw.githubusercontent.com/facebook/react-native-fbsdk/master/bin/ios_setup.js
npm install plist xcode adm-zip
node ios_setup.js [App ID] [App Name]
If you inspect the script, it installs FBSDKCoreKit, FBSDKShareKit, FBSDKLoginKit for us.
const target = myProj.getFirstTarget().uuid;
myProj.addFramework('./ios/Frameworks/FBSDKCoreKit.framework', { 'customFramework': true, 'target': target, 'link': true });
myProj.addFramework('./ios/Frameworks/FBSDKShareKit.framework', { 'customFramework': true, 'target': target, 'link': true });
myProj.addFramework('./ios/Frameworks/FBSDKLoginKit.framework', { 'customFramework': true, 'target': target, 'link': true });
Setup for Android
Follow Android with React Native v0.30+ Project Configuration and add Facebook SDK code in MainApplication.java
and MainActivity.java
Also as stated by react-native-fbsdk, you should declare Facebook App Id. Follow Quick Starts for Android platform for how to add Facebook App ID in strings.xml
and declare com.facebook.sdk.ApplicationId
in AndroidManifest.xml
In case you want to change package name for Android project, you can do so in Visual Studio Code and remember to update relevant package name. Or the recommended way is to do so in Android Studio
I had a problem with sdkInitialize
and the solution is to just remove them. Here is how onCreate
looks in MainApplication.java
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
Navigation
There has been quite a lot of navigation frameworks for React Native, but the most popular right now is React Navigation. Let’s start by adding npm install — save react-navigation
.
We will create LoginNavigator
to manage the login flow, and MainNavigator
to manage after login flow. We switch between the 2 depending on Facebook login status. I like to separate code into components, here is the folder structure
Switch Navigator
As of react-navigation 2.11.2
in this project, it uses makeXXX
for creating navigators. Let’s use SwitchNavigator
to switch between MainNavigator
and LoginNavigator
depending on the existence of Facebook access token
Below are MainNavigator
which uses bottom TabNavigator
For now the LoginNavigator is just a StackNavigator
with just the LoginPage
Login with Facebook
Let’s make a convenient FacebookService
to deal with Facebook SDK
Here we wrap GraphRequest
inside Promise to use async await
style, you can read more about async await
and the difference between export const
and export default
Login with FacebookService in LoginPage
Every component managed by react-navigation
is given a property called navigation
that we can call to transit to new page.
We can manually use LoginManager to have my fine grain control, but here a LoginButton
works well. It also shows Login or Logout text depending on login status.
Take note that we bind
login method to LogInPage
to properly handle event in React
react-navigation
supports passing parameters between Navigators, but here we can just need Access Token from FacebookService which we can easily retrieve.
Notice that you may get limit if you make lots of Facebook requests, and there’s problem with declaring both read and publish permissions in LoginButton
Show Facebook info in ProfilePage
For a cool UI toolkit in React Native, let’s use react-native-elements. We use that in ProfilePage
Since ProfilePage
is managed within react-navigation
, we can easily transition to new MainNavigator
with this.props.navigation.navigate(‘LoginNavigator’)
. I also use SafeAreaView
to make it look good on iPhone X. SafeAreaView
defaults to empty View
in Android
The ProfileView
is the header containing Facebook profile information, this is to split responsibilities in term of layout.
Tips and troubleshooting
During working with React Native and Facebook SDK, I got some problems and learn a lot. Most of the time they are well known problems and a search on internet can show you the answer. Below are few tips and troubleshooting that may help.
A few tips
How to print console log in Android
Follow Debugging and run react-native log-android
or adb logcat
. Also press Cmd+M
to open live reload menu. For how to add adb
to PATH
, run
export PATH="/Users/khoa/Library/Android/sdk/platform-tools":$PATH
Add sdk.dir = /Users/USERNAME/Library/Android/sdk
to local.properties
file
Understand module system in React
Read the awesome blog post below and you are no long confused
Troubleshooting
Nothing is given free. The power of React Native comes with lots of problems, you can’t believe how much time you wasted diving in issues.
No bundle URL present
Check that you import the module with the right name, case insensitivity is often the culprit. Also most the time caching or wrong state is the issue, there you just need to clear the cache rm -rf ios/build/
or kill the current process kill $(lsof -t -i:8081)
You may also need to close / reset content in iOS simulator and Android emulator. Make sure you see bundle 100%.
React-Native: Module AppRegistry is not a registered callable module
You should be careful when to use brackets for import
Possible unhandled promise rejection
This is just warning, but you should catch
when dealing with Promise
Packager can’t listen on port 8081
Either start with different port react-native start --port=8088
or find process that uses port 8081 sudo lsof -i :8081
and kill with its PID
kill -9 PID
Where to go from here
I hope this article helps a bit in integrating Facebook SDK into React Native apps. Besides I think learning how variable scopes and Flexbox work will benefit you in the long run with React Native.
Understand var
Javascript may be a weird language, but before you understand how block scope and function scope work with var, let, const
, especially in loop
Learning Flexbox
Flexbox is preferred way to do layout in React apps. Doing it wrong and the whole layout disappears or messes up.
❤️ Support my apps ❤️
- Push Hero — pure Swift native macOS application to test push notifications
- PastePal — Pasteboard, note and shortcut manager
- Quick Check — smart todo manager
- Alias — App and file shortcut manager
- My other apps
❤️❤️😇😍🤘❤️❤️