react-native-branch-deep-linking-attribution
react-native-branch-deep-linking-attribution copied to clipboard
Ios configuration with react-native-linking is duplicated with react-native-branch's
I'm trying to integrate react navigation with this react-native-branch In react-navigation docs, they say it can be used with branch like this
But I found both of libraries need to configure same function on AppDelegete.m
1 . for react-native-linking
// Linking API (react-native-linking)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [RCTLinkingManager application:application openURL:url options:options];
}
// Universal Links(react-native-linking)
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- for react-native-branch
// Branch.io
- (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;
}
// Universal Links(Branch.io)
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
return [RNBranch continueUserActivity:userActivity];
}
so I needed to chose what to use.
- if I chose 1. react-native-linking configuration , I can use linking configuration which react-navigion5 provide. and
- branch.getFirstReferringsParms()
work.
-branch.subscribe(({params}) =>{...}) seems to work, but the params it giving me is always {“+clicked_branch_link”: false, “+is_first_session”: false} or {“+clicked_branch_link”: false, “+is_first_session”: false, “+rn_cached_initial_event”: true}
no other custom params,
-branch.getLastesReferringsParams() also return same with subscribe. no custom params.
- so I replaced AppDelegate.m with 2. react-native-branch configuration in this way, linking configuration has no effect. Not triggered
but -branch.getLastesReferringsParams() give me the exact params that i sended with. branch.subscribe() also work.
So I'm planning to chose react-native-branch configuration ..
but this means the way doc say is not correct.
Is there any way that i can use react-navigation5 's linking configuration while getting correct latestParams ??
same issue :(
still an issue
Hi Everyone! I'fe found the solution!! Both configurations are compatible (deep linking and branch), but it is not documented anywhere. In order to make the config screens work in react navigation and branch, add or modify these two methods in the AppDelegate.m:
#import <RNBranch/RNBranch.h>
#import <React/RCTLinkingManager.h>
- (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
[[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
}
return [RCTLinkingManager application:app openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
return [RNBranch continueUserActivity:userActivity] || [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}
and the navigator should look like this:
<NavigationContainer
ref={navigationRef}
linking={{
prefixes: ["https://yourapp.com", "yourapp://"],
config: {
screens: {
[EVENT]: {
path: "events/:eventId",
parse: {
eventId: decodeEventId
}
}
}
},
// Custom function to subscribe to incoming links
subscribe(listener) {
// First, you may want to do the default deep link handling
const onReceiveURL = ({ url }) => listener(url);
// Listen to incoming links from deep linking
Linking.addEventListener("url", onReceiveURL);
// Next, you would need to subscribe to incoming links from your third-party integration
// For example, to get to subscribe to incoming links from branch.io:
branch.subscribe(({ error, params, uri }) => {
if (error) {
handleError(`Error from Branch: ${error}`);
return;
}
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
const url = params.$canonical_url;
const eventId = url.replace("events/", "");
// routing depending on deep link
listener(\`/events/${eventId}\`);
});
return () => {
// Clean up the event listeners
Linking.removeEventListener("url", onReceiveURL);
};
},
async getInitialURL() {
// First, you may want to do the default deep link handling
// Check if app was opened from a deep link
const url = await Linking.getInitialURL();
// routing depending on deep link
if (url != null) {
return url;
}
// Next, you would need to get the initial URL from your third-party integration
// It depends on the third-party SDK you use
// For example, to get to get the initial URL for branch.io:
const params = await branch.getFirstReferringParams();
return params?.$canonical_url;
}
}}
>
<MainNavigator />
</NavigationContainer>
This way, all links are opened by the native deep linking system and routed through it. Independently of routing, onsubscribe callback from rn branch is executed so that branch api is aware of your click.
Hi Everyone! I'fe found the solution!! Both configurations are compatible (deep linking and branch), but it is not documented anywhere. In order to make the config screens work in react navigation and branch, add or modify these two methods in the AppDelegate.m:
#import <RNBranch/RNBranch.h> #import <React/RCTLinkingManager.h> - (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 [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options]; } return [RCTLinkingManager application:app openURL:url options:options]; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler { return [RNBranch continueUserActivity:userActivity] || [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; }
and the navigator should look like this:
<NavigationContainer ref={navigationRef} linking={{ prefixes: ["https://yourapp.com", "yourapp://"], config: { screens: { [EVENT]: { path: "events/:eventId", parse: { eventId: decodeEventId } } } }, // Custom function to subscribe to incoming links subscribe(listener) { // First, you may want to do the default deep link handling const onReceiveURL = ({ url }) => listener(url); // Listen to incoming links from deep linking Linking.addEventListener("url", onReceiveURL); // Next, you would need to subscribe to incoming links from your third-party integration // For example, to get to subscribe to incoming links from branch.io: branch.subscribe(({ error, params, uri }) => { if (error) { handleError(`Error from Branch: ${error}`); return; } 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 const url = params.$canonical_url; const eventId = url.replace("events/", ""); // routing depending on deep link listener(\`/events/${eventId}\`); }); return () => { // Clean up the event listeners Linking.removeEventListener("url", onReceiveURL); }; }, async getInitialURL() { // First, you may want to do the default deep link handling // Check if app was opened from a deep link const url = await Linking.getInitialURL(); // routing depending on deep link if (url != null) { return url; } // Next, you would need to get the initial URL from your third-party integration // It depends on the third-party SDK you use // For example, to get to get the initial URL for branch.io: const params = await branch.getFirstReferringParams(); return params?.$canonical_url; } }} > <MainNavigator /> </NavigationContainer>
This way, all links are opened by the native deep linking system and routed through it. Independently of routing, onsubscribe callback from rn branch is executed so that branch api is aware of your click.
do you know if there is a way to implement this on the android side? because I'm having the same issue but on android, also this
not sure why got this error

Thank you for help me to resolve issue with RCTLinkingManager. I written a plugin to use react-native-branch with expo
@Vasault
iOS:
- replace
app
withapplication
- if you no need routing for FB etc. you can simply return nil
like that:
// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([RNBranch application:application openURL:url options:options]) {
// do other deep link routing for the Facebook SDK, Pinterest SDK, etc
return nil;
}
return [RCTLinkingManager application:application openURL:url options:options];
}
Android:
Make sure that in MainActivity.java
onNewIntent
method looks like:
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
RNBranchModule.onNewIntent(intent);
}
@cbarceloc Thank you for this! But shouldn't we add return
before
[[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];