Creating a Referral System Using Branch in React Native
Go viral by rewarding your users for sharing your app
A referral system can be a great tool to get users to share your app with their friends and get new users using your app. In this tutorial I will show you how to build a great referral system similar to Uber, AirBnB, and many other startups.
In this tutorial I will show you how to:
- Integrate Branch into your React Native project
- Create referral links your users can share to earn rewards
- Determine awards on specific events
- Allow users to redeem these credits in your app
Getting Started
While the Branch.io docs are good we’re going to advise you to not add Branch with the Podfile as we had duplicate file errors in Xcode. We used the following:
Install the Branch SDK
// first// yarn
yarn add react-native-branch// npm
npm i --save react-native-branch// thenreact-native link react-native-branch
Configure Branch Dashboard
Signup for Branch.io and to your dashboard and follow this guide: https://docs.branch.io/pages/dashboard/integrate/
Configure iOS
Add your bundle identifier to the Branch Dashboard like below and confirm they match.
Go to Project -> Capabilities -> Associated Domains. Add your app link that you configured in your dashboard here. For instance if your link is medium
you would use that in place of ethan
in ethan.app.link
like below. In our configuration we have testing and alternative links as well.
Add your Branch info to your Info.plist. Create new entries branch_app_domain
and branch_key
and associate them to the values found in your Branch Dashboard.
In AppDelegate.m
add the following for Objective-C:
// Initialize the Branch Session at the top of existing application:didFinishLaunchingWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Uncomment this line to use the test key instead of the live one.
// RNBranch.useTestInstance()
RNBranch.initSession(launchOptions: launchOptions, isReferrable: true) // <-- add this
//...
}
// Add the openURL and continueUserActivity functions
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return RNBranch.branch.application(app, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
return RNBranch.continue(userActivity)
}
For Swift:
/ Initialize the Branch Session at the top of existing application:didFinishLaunchingWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Uncomment this line to use the test key instead of the live one.
// RNBranch.useTestInstance()
RNBranch.initSession(launchOptions: launchOptions, isReferrable: true) // <-- add this
//...
}
// Add the openURL and continueUserActivity functions
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return RNBranch.branch.application(app, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
return RNBranch.continue(userActivity)
}
Configure Android
In your AndroidManifest.xml
add the following changes replacing the values of the following from your dashboard and ignore ://
in your Manifest scheme:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eneff.branchandroid">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:name="com.eneff.branchandroid.CustomApplicationClass"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Branch URI Scheme -->
<intent-filter>
<data android:scheme="branchandroid" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<!-- Branch App Links (optional) -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="uobg.app.link" />
</intent-filter>
</activity>
<!-- Branch init -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_gdzsepIaUf7wG3dEWb3aBkmcutm0PwJa" />
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_edwDakKcMeWzJ3hC3aZs9kniyuaWGCTa" />
<meta-data android:name="io.branch.sdk.TestMode" android:value="false" />
<!-- Branch install referrer tracking (optional) -->
<receiver android:name="io.branch.referral.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
</manifest>
Open android/app/proguard-rules.pro
and add the following:
-dontwarn io.branch.**
In MainApplication.java
add:
// ...
// import Branch and RNBranch
import io.branch.rnbranch.RNBranchPackage;
import io.branch.referral.Branch;
//...
// add RNBranchPackage to react-native package list
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNBranchPackage(), // <-- add this
// ...
// add onCreate() override
@Override
public void onCreate() {
super.onCreate();
Branch.getAutoInstance(this);
}
And to MainActivity.java
:
import io.branch.rnbranch.*; // <-- add this
import android.content.Intent; // <-- and this
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "base";
}
// Override onStart, onNewIntent:
@Override
protected void onStart() {
super.onStart();
RNBranchModule.initSession(getIntent().getData(), this);
}
@Override
public void onNewIntent(Intent intent) {
setIntent(intent);
}
// ...
}
Creating a Shareable Link
Now that we have Branch configured we need to create a shareable link that will allow us to identify users in our app. You do this by adding code that uniquely identifies your user when they register or login.
import branch from 'react-native-branch' // <- import branch branch.setIdentity('theUserId') // <- Identifiy the user in branch
When the user logs off we would run the following code:
branch.logout()
Now that we can identify the user we create a shareable link the user can share. Any referrals using this link will automatically be tracked to the user. We created this link using the following code and use it whenever the user wants to create a referral:
async shareReferralLink() { let branchUniversalObject = await branch.createBranchUniversalObject('canonicalIdentifier', {
automaticallyListOnSpotlight: true,
metadata: {prop1: 'test', prop2: 'abc'},
title: 'Cool Content!',
contentDescription: 'Cool Content Description'}) let linkProperties = {
feature: 'share',
channel: 'facebook'
} let controlParams = {
$desktop_url: 'http://desktop-url.com/monster/12345'
} let shareOptions = { messageHeader: 'Check this out', messageBody: 'No really, check this out!' } let {channel, completed, error} = await
branchUniversalObject.showShareSheet(shareOptions, linkProperties, controlParams)}
Rewarding Users
To determine how much each user has earned go to your Branch Dashboard then Referrals -> Reward Rules. Add a rule which should look like this:
Some Terminology
- All acting users: Both the referring and referred user
- Referring user: The user who shared the link
- Referred acting user: the new user
If you would like to credit both users the same amount when an event occurs (I.e Both users get 5 credits when referred acting user installs the app) then select All acting users
. Then select the credit amount with the event that triggers that creates the reward.
If you would like to assign different credit amount for each user type or for different events setup different rules.
Events
The Event is the action the user takes to earn the reward. This could be when they signup or create a purchase. In Uber the referred user receives a credit when they signup and the referring user receives a credit when the invitee takes their first ride.
Branch has presets for INSTALL and SHARING A LINK. To create a custom event you would use the following code and replace signup
with the event name of your choice:
branch.userCompletedAction(‘signup’, {})
Now Branch will automatically award the credits when the event is triggered depending on the rules you set in your dashboard.
Allowing Users to Redeem Credit
In order for users to redeem credit from their referrals we need to know how much they’ve earned. We can do that with the following:
let rewards = await branch.loadRewards()
If the user has earned enough credits we can redeem their rewards by choosing a reward rule that we’ve defined in our dashboard. Using our defulat bucket we redeem the user’s reward with the following:
let redeemResult = await branch.redeemRewards(1, 'default')
That’s it! We now have a fully working referrals system in our react native app and we can being rewarding our users for sharing our app with their friends.
Thanks for reading! Please feel free to reach out the in the comments below with questions or suggestions.
Menan