React Native
Inconsistent Universal links behavior on iOS 11.2
After updating a device to iOS 11.2, we found that the app's AASA file is no longer downloaded reliably onto your user’s device after an app install. As a result, clicking on Universal links will no longer open the app consistently. You can set forced uri redirect mode on your Branch links to open the app with URI schemes. View details of the issue on the Apple Bug report.
Google Play Services version 17+
If you reference Google Play Services version 17 or higher, you MUST complete Google's update instructions here.
Due to a major Google Play Services change made in June 2019, not completing the update steps will cause Branch's Android SDK (and various other cross-platform SDKs, e.g. Unity) to stop collecting Android AID which we use to ensure accurate deep linking and attribution.
If you are running Google Play Services versions below 17, no update is necessary.
Configure Branch
- Configure your Default Link Settings.
Install Branch
Option 1: Pure React Native App
Expo Note: If you are working with Expo, you must first eject your app from Expo, use the Expo Bare Workflow and follow the instructions below.
expo eject
Note: react-native-branch requires react-native >= 0.60
- Install the module
yarn add [email protected]^5.0.0
npm install --save [email protected]^5.0.0
- (Optional) Add a branch.json file to the root of your app (next to package.json).
You can configure the contents at any time, but it must be present when you run react-native link
in order to be automatically included in your native projects. This allows you to configure certain behaviors that otherwise require native code changes. See https://rnbranch.app.link/branch-json for full details on the branch.json file.
Option 2: Native iOS app with CocoaPods
- Add these lines to your
Podfile
pod 'react-native-branch', path: '../node_modules/react-native-branch'
-
Run
pod install
to regenerate thePods
project with the new dependencies. Note that the location ofnode_modules
relative to yourPodfile
may vary. -
(Optional) Add a branch.json file to the root of your app (next to package.json). See https://rnbranch.app.link/branch-json.
Updating from an earlier version or starting with v5.0.0
iOS
- In the AppDelegate, replace
[RNBranch.branch application:app openURL:url options:options]
with[RNBranch application:app openURL:url options:options]
(RNBranch.branch => RNBranch
), e.g.
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RNBranch application:app openURL:url options:options];
}
Android
- In
MainActivity.onNewIntent
, replacesetIntent(intent)
withRNBranchModule.onNewIntent(intent)
, e.g.
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null &&
intent.hasExtra("branch_force_new_session") &&
intent.getBooleanExtra("branch_force_new_session",false)) {
RNBranchModule.onNewIntent(intent);
}
}
Configure App
iOS
-
Configure bundle identifier
-
Bundle Id matches Branch Dashboard
-
-
Configure associated domains
-
Add your link domains from your Branch Dashboard
-
-alternate
is needed for Universal Linking with the Web Basic Integration inside your Website. -
test-
is needed if you need use a test key -
If you use a custom link domain, you will need to include your old link domain, your
-alternate
link domain, and your new link domain
-
-
Configure entitlements
-
Confirm entitlements are within TARGETS
-
-
Configure Info.plist
-
Add Branch Dashboard values
- Add
branch_universal_link_domains
with your live key domain - Add
branch_key
with your current Branch keys - Add your URI scheme as
URL Types
->Item 0
->URL Schemes
- Add
-
-
Confirm app prefix
-
From your Apple Developer Account
-
Android
AndroidManifest.xml
<?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" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<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" android:host="open" />
<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 -->
<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" />
<data android:scheme="https" android:host="uobg-alternate.app.link" />
</intent-filter>
</activity>
<!-- Branch keys -->
<!-- (Omit if setting keys in branch.json) -->
<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"/>
</application>
</manifest>
-
Replace the following with values from your Branch Dashboard
branchandroid
uobg.app.link
key_live_gdzsepIaUf7wG3dEWb3aBkmcutm0PwJa
key_test_edwDakKcMeWzJ3hC3aZs9kniyuaWGCTa
-
android/app/proguard-rules.pro
-dontwarn io.branch.**
Initialize Branch
iOS
Objective-C
Add `#import <RNBranch/RNBranch.h> to your AppDelegate.m.
Swift
If you have use_frameworks!
in your Podfile, add import RNBRanch
to your AppDelegate.swift.
If you do not have use_frameworks!
in your Podfile, add #import <RNBranch/RNBranch.h>
to your Bridging header if you have one.
import RNBranch
// import react_native_branch // with 3.x
// 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.application(app, open:url, options:options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
return RNBranch.continue(userActivity)
}
#import <RNBranch/RNBranch.h> // at the top
// #import <react-native-branch/RNBranch.h> // with 3.x
// Initialize the Branch Session at the top of existing application:didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Uncomment this line to use the test key instead of the live one.
// [RNBranch useTestInstance];
[RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES]; // <-- add this
NSURL *jsCodeLocation;
//...
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([RNBranch application:app openURL:url options:options]) {
// do other deep link routing for the Facebook SDK, Pinterest SDK, etc
}
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
return [RNBranch continueUserActivity:userActivity];
}
Android
MainApplication.java
// ...
// import from RNBranch
import io.branch.rnbranch.RNBranchModule;
//...
// add onCreate() override
@Override
public void onCreate() {
super.onCreate();
RNBranchModule.getAutoInstance(this);
}
// ...
// imports from RNBranch
import io.branch.rnbranch.RNBranchModule;
import io.branch.rnbranch.RNBranchPackage;
//...
// 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();
RNBranchModule.getAutoInstance(this);
}
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) {
super.onNewIntent(intent);
if (intent != null &&
intent.hasExtra("branch_force_new_session") &&
intent.getBooleanExtra("branch_force_new_session",false)) {
RNBranchModule.onNewIntent(intent);
}
}
// ...
}
Implement Features
Import Branch
- In any React Native source file that uses the Branch SDK.
import branch, { BranchEvent } from 'react-native-branch'
Create content reference
-
The Branch Universal Object encapsulates the thing you want to share (content or user)
-
Uses the Universal Object Properties
// only canonicalIdentifier is required
let branchUniversalObject = await branch.createBranchUniversalObject('canonicalIdentifier', {
locallyIndex: true,
title: 'Cool Content!',
contentDescription: 'Cool Content Description',
contentMetadata: {
ratingAverage: 4.2,
customMetadata: {
prop1: 'test',
prop2: 'abc'
}
}
})
Create deep link
-
Creates a deep link URL with encapsulated data
-
Needs a Branch Universal Object
-
Uses Deep Link Properties
-
Validate with the Branch Dashboard
let linkProperties = {
feature: 'share',
channel: 'facebook'
}
let controlParams = {
$desktop_url: 'http://desktop-url.com/monster/12345'
}
let {url} = await branchUniversalObject.generateShortUrl(linkProperties, controlParams)
Share deep link
-
Will generate a Branch deep link and tag it with the channel the user selects
-
Needs a Branch Universal Object
-
Uses Deep Link Properties
let shareOptions = { messageHeader: 'Check this out', messageBody: 'No really, check this out!' }
let linkProperties = { feature: 'share', channel: 'RNApp' }
let controlParams = { $desktop_url: 'http://example.com/home', $ios_url: 'http://example.com/ios' }
let {channel, completed, error} = await branchUniversalObject.showShareSheet(shareOptions, linkProperties, controlParams)
Read deep link
-
Retrieve Branch data from a deep link
-
Best practice to receive data from the
listener
(to prevent a race condition) -
Returns deep link properties
-
Listener
branch.subscribe(({error, params, uri}) => {
if (error) {
console.error('Error from Branch: ' + error)
return
}
// params will never be null if error is null
})
let lastParams = await branch.getLatestReferringParams() // params from last open
let installParams = await branch.getFirstReferringParams() // params from original install
NativeLink™ Deferred Deep Linking (iOS Only)
- Use iOS pasteboard to enable deferred deep linking via Branch NativeLink™
Prerequisites
Make sure you are on v5.0.4+
To use this feature you must:
- Enable NativeLink™ Deep Linking in the Branch Dashboard Configuration tab
or- Manually configure your Branch Link to use
$ios_nativelink
Implement one of the pasteboard opt-in options in the native iOS SDK code or through the JS Layer:
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[AppCenterReactNative register];
[AppCenterReactNativeAnalytics registerWithInitiallyEnabled:true];
[AppCenterReactNativeCrashes registerWithAutomaticProcessing];
[GMSServices provideAPIKey:@"__________________"];
...
[RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES ];
[RNBranch.branch checkPasteboardOnInstall];
...
return YES;
}
Navigate to content
branch.subscribe(({error, params, uri}) => {
if (error) {
console.error('Error from Branch: ' + error)
return
}
// params will never be null if error is null
if (params['+non_branch_link']) {
const nonBranchUrl = params['+non_branch_link']
// Route non-Branch URL if appropriate.
return
}
if (!params['+clicked_branch_link']) {
// Indicates initialization success and some other conditions.
// No link was opened.
return
}
// A Branch link was opened.
// Route link based on data in params, e.g.
// Get title and url for route
const title = params.$og_title
const url = params.$canonical_url
const image = params.$og_image_url
// Now push the view for this URL
this.navigator.push({ title: title, url: url, image: image })
})
Adjust cached link TTL
-
Any link that launched the app is cached by the native layers and returned to the
branch.subscribe
listener after JavaScript finishes loading. -
By default, the initial link is cached for 5 seconds. This allows you to unsubscribe and resubscribe later without receiving the initial link.
-
If your app takes longer than this to load, you can adjust the TTL for the initial link by adjusting
branch.initSessionTtl
to a value in milliseconds.
branch.initSessionTtl = 10000 // Set to 10 seconds
branch.subscribe({ error, params } => {
// ...
})
Display content
-
List content on iOS Spotlight
-
Needs a Branch Universal Object
-
Listing on Spotlight requires adding
CoreSpotlight.framework
to your Xcode project.
let branchUniversalObject = await branch.createBranchUniversalObject('canonicalIdentifier', {
locallyIndex: true,
// other properties
})
branchUniversalObject.logEvent(BranchEvent.ViewItem)
Track content
-
Track how many times a piece of content is viewed
-
Needs a Branch Universal Object
-
Uses Track content properties
-
Validate with the Branch Dashboard
import { BranchEvent } from 'react-native-branch'
branchUniversalObject.logEvent(BranchEvent.ViewItem)
Track users
-
Sets the identity of a user (email, ID, UUID, etc) for events, deep links, and referrals
-
Validate with the Branch Dashboard
branch.setIdentity('theUserId')
branch.logout()
Track events
-
Track standard and custom events
-
Events named
open
,close
,install
, andreferred session
are Branch restricted -
63
max event name length -
Best to Track users before Track events to associate a custom event to a user
-
Validate with the Branch Dashboard
import { BranchEvent } from 'react-native-branch'
// Associate one or more content items with an event
new BranchEvent(BranchEvent.ViewItems, [buo1, buo2]).logEvent()
// Log a standard event with parameters
new BranchEvent(BranchEvent.Purchase, buo, {
revenue: 20,
shipping: 2,
tax: 1.6,
currency: 'USD'
}).logEvent()
// Set parameters after initialization
let event = new BranchEvent(BranchEvent.Search)
event.searchQuery = "tennis rackets"
event.logEvent()
// Log a custom event
new BranchEvent("UserScannedItem", buo).logEvent()
- When logging an event with a single Branch Universal Object, use the convenient logEvent method
buo.logEvent(BranchEvent.ViewItem)
buo.logEvent(BranchEvent.Purchase, { revenue: 20 })
Standard events
Event constant | Description |
---|---|
BranchEvent.AddToCart | Standard Add to Cart event |
BranchEvent.AddToWishlist | Standard Add to Wishlist event |
BranchEvent.ViewCart | Standard View Cart event |
BranchEvent.InitiatePurchase | Standard Initiate Purchase event |
BranchEvent.AddPaymentInfo | Standard Add Payment Info event |
BranchEvent.Purchase | Standard Purchase event |
BranchEvent.SpendCredits | Standard Spend Credits event |
BranchEvent.Search | Standard Search event |
BranchEvent.ViewItem | Standard View Item event for a single Branch Universal Object |
BranchEvent.ViewItems | Standard View Items event for multiple Branch Universal Objects |
BranchEvent.Rate | Standard Rate event |
BranchEvent.Share | Standard Share event |
BranchEvent.CompleteRegistration | Standard Complete Registration event |
BranchEvent.CompleteTutorial | Standard Complete Tutorial event |
BranchEvent.AchieveLevel | Standard Achieve Level event |
BranchEvent.AchievementUnlocked | Standard Unlock Achievement event |
Handle links in your own app
- Allows you to deep link into your own from your app itself
branch.openURL("https://example.app.link/u3fzDwyyjF")
branch.openURL("https://example.app.link/u3fzDwyyjF", {newActivity: true}) // Finish the Android current activity before opening the link. Results in a new activity window. Ignored on iOS.
Handling a new deep link
Handling a new deep link in your app will clear the current session data and a new referred "open" will be attributed.
Handle push notifications
-
Allows you to track Branch deep links in your push notifications
-
Use openURL to handle the deep links
Track Apple Search Ads
-
Allows Branch to track Apple Search Ads deep linking analytics
-
Analytics from Apple's API have been slow which will make our analytics lower. Additionally, Apple's API does not send us all the data of an ad every time which will make ads tracked by us to show a generic campaign sometimes.
-
This requires an option to be set before the native SDK initializes, which
happens before JS finishes loading. There are two options:- Add
"delayInitToCheckForSearchAds": true
to yourbranch.json
file:
- Add
{
"delayInitToCheckForSearchAds": true
}
- Modify your AppDelegate in Xcode. Insert the following before the call to
[RNBranch initSessionWithLaunchOptions:isReferrable:]
.
Branch.getInstance().delayInitToCheckForSearchAds()
[[Branch getInstance] delayInitToCheckForSearchAds];
Enable 100% matching
Android
-
Uses Chrome Tabs to increase attribute matching success
-
Add
implementation 'com.android.support:customtabs:28.0.0'
to yourbuild.gradle
iOS
-
Uses the
SFSafariViewController
to increase the attribution matching success -
The 100% match is a bit of a misnomer, as it is only 100% match from when a user clicks from the Safari browser. According to our analysis, clicking through Safari happens about 50-75% of the time depending on the use case. For example, clicking from Facebook, Gmail or Chrome won’t trigger a 100% match here. However, it’s still beneficial to the matching accuracy, so we recommend employing it.
-
When using a custom domain, add a
branch_app_domain
string key in your Info.plist with your custom domain to enable 100% matching. -
By default, cookie-based matching is enabled on iOS 9 and 10 if the
SafariServices.framework
is included in an app's dependencies, and the app uses an app.link subdomain or sets thebranch_app_domain
in the Info.plist. It can be disabled with a call to the SDK. -
Add before
initSession
Initialize Branch
Branch.getInstance().disableCookieBasedMatching()
[[Branch getInstance] disableCookieBasedMatching];
Append metadata to Branch network call
- Functions to append additional metadata, for use cases like inserting user ID's to enable third-party Data Integrations
iOS
RNBranch.setRequestMetadataKey("insert_user_id", "value")
Android
RNBranchModule.setRequestMetadata("userID", "value");
Receive notification before a link is opened
Requires react-native-branch 5.x
To be notified that Branch is about to open a link, use an onOpenStart
callback with branch.subscribe
. Also supply an onOpenComplete
callback, which is the same as the single callback usually used with branch.subscribe
:
import branch from 'react-native-branch';
branch.subscribe({
onOpenStart: ({uri, cachedInitialEvent}) => {
// cachedInitialEvent is true if the event was received by the
// native layer before JS loaded.
console.log('Branch will open ' + uri);
},
onOpenComplete: ({error, params,uri}) => {
if (error) {
console.error('Error from Branch opening uri ' + uri);
return;
}
console.log('Branch opened ' + uri);
// handle params
},
})
Note that uri will be null in some cases, particularly in the case of a deferred deep link. In these cases, consult the params for ~referring_link, +url or +non_branch_link to determine the referring URI/URL.
Remove iOS AdSupport Framework
If you do not want your app collecting the IDFA in any instance whatsoever, you must remove the AdSupport
framework that React Native includes by default in its build. As long as this framework exists in the build, Branch is triggered to request the IDFA.
To remove the AdSupport
framework:
- Search for
GCC_PREPROCESSOR_DEFINITIONS
. - Locate
Branch.debug.xcconfig
andBranch.release.xcconfig
. - Edit the preprocessor line to
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 BRANCH_EXCLUDE_IDFA_CODE=1
. - Clean and rebuild.
- If you breakpoint in
BNCSystemObserver.m
atgetAdId,
it should now always return nil.
Troubleshoot Issues
Test deep link iOS
-
Create a deep link from the Branch Marketing Dashboard
-
Delete your app from the device
-
Compile your app with Xcode
-
Paste deep link in Apple Notes
-
Long press on the deep link (not 3D Touch)
-
Click Open in "APP_NAME" to open your app (example)
Test deep link Android
-
Create a deep link from the Branch Marketing Dashboard
-
Delete your app from the device
-
Compile your app with Android Studio
-
Paste deep link in Google Hangouts
-
Click on the deep link to open your app
Use test key
-
Use the Branch
test key
instead of thelive key
. -
In iOS, add before
initSession
Initialize Branch. -
In iOS, update
branch_key
in yourInfo.plist
to a dictionary (example). -
In Android, set
test mode
totrue
. -
The
test key
of your app must match thetest key
of your deep link. -
Use conditional compilation or remove before releasing to production.
#if DEBUG
RNBranch.useTestInstance()
#endif
#if DEBUG
RNBranch.useTestInstance()
#endif
- Android: Use this in a build type or product flavor or be sure to remove before
releasing to production.
<meta-data android:name="io.branch.sdk.TestMode" android:value="true" />
Simulate an install
Do not test in production.
This requires a native method call that must be made before JS has loaded. There are two options.
- Use a
branch.json
file with your project. See https://rnbranch.app.link/branch-json for full details.
Add"debugMode": true
tobranch.debug.json
:
{
"appleSearchAdsDebugMode": true,
"debugMode": true,
"delayInitToCheckForSearchAds": true
}
Do not add this setting to branch.json
, or it will be enabled for release builds.
- Modify your native app code.
Android
Simulated installs may be enabled on Android by adding <meta-data android:name="io.branch.sdk.TestMode" android:value="true"/>
to the application
element of your Android manifest. Use this in a build type such as debug
or a product flavor, or be sure to remove it from your manifest before releasing to prod. Click here for more details.
Alternately, add RNBranchModule.setDebug();
in your MainActivity before the call to initSession
. Be sure to remove it before releasing to prod.
// Remove before prod release
RNBranchModule.setDebug();
RNBranchModule.initSession(getIntent().getData(), this);
iOS
Add [RNBranch enableLogging];
or RNBranch.enableLogging()
in your AppDelegate before the call to initSession
.
Use conditional compilation or remove before releasing to prod.
#if DEBUG
RNBranch.enableLogging()
#endif
RNBranch.initSession(launchOptions: launchOptions, isReferrable: true)
#ifdef DEBUG
[RNBranch enableLogging];
#endif
[RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];
Using getLatestReferringParams to handle link opens
The getLatestReferringParams
method is essentially a synchronous method that retrieves the latest referring link parameters stored by the native SDK. However, React Native does not support synchronous calls to native code from JavaScript, so the method returns a promise. You must await
the response or use then
to receive the result. The same remarks apply to the getFirstReferringParams
method.
However, this is only a restriction of React Native. The purpose of getLatestReferringParams
is to retrieve those parameters one time. The promise will only return one result. It will not continue to return results when links are opened or wait for a link to be opened. This method is not intended to notify the app when a link has been opened.
To receive notification whenever a link is opened, including at app launch, call
branch.subscribe
. The callback to this method will return any initial link that launched the
app and all subsequent link opens. There is no need to call getLatestReferringParams
at app launch to check for an initial link. Use branch.subscribe
to handle all link opens.
Common build problems
-
Be sure to follow the instructions to Update from < 2.0.0 if your
app used an earlier version of react-native-branch. In version 2.x, the native SDKs are embedded
in the NPM module and must not also be added from elsewhere (Gradle, CocoaPods, etc.). -
Note that when using the
React
pod in a native app, the name of the native SDK pod isBranch-SDK
, notBranch
, and it comes fromnode_modules
, not the CocoaPods repo. -
Starting with React Native 0.40, all external iOS headers in Objective-C must be imported as
#import <PackageName/Header.h>
. This applies to React Native headers as well as the<react-native-branch/RNBranch.h>
header from this SDK. -
If you upgraded from RN < 0.40 manually, without adjusting your Xcode project settings, you may
still be importing headers with double quotes. This probably indicates a problem with your settings. -
The
react-native-git-upgrade
tool from NPM may be used to update dependencies as well as project settings. -
On Android, when using Proguard in release builds, depending on your build settings, it may be
necessary to add one or both of these lines to yourandroid/app/proguard-rules.pro
file:
-dontwarn com.crashlytics.android.answers.shim.**
-dontwarn com.google.firebase.appindexing.**
General troubleshooting
See the troubleshooting guide for each native SDK:
Sample apps
Updated 12 days ago