react-native-branch-deep-linking-attribution icon indicating copy to clipboard operation
react-native-branch-deep-linking-attribution copied to clipboard

How to setRequestMetadataKey for segment

Open 0xpatrickdev opened this issue 6 years ago • 20 comments

Hey folks,

The documentation on the website is a little sparse/unclear for React Native.

There are two PR's (for iOS and Android) that seem to implement the setRequestMetadataKey method: #210 & #321, but they are unfortunately not documented.

Here are the relevant excerpts from the Branch website:

iOS: Inside didFinishLaunchingWithOptions

Branch *branch = [Branch getInstance];
[[Branch getInstance] setRequestMetadataKey:@"$segment_anonymous_id" value:[[SEGAnalytics sharedAnalytics] getAnonymousId]];

Android: Before you initialize in your Application#onCreate or Deep Link Activity's #onCreate.

Branch.getInstance().setRequestMetadata("$segment_anonymous_id", com.segment.analytics.Analytics.with(this).getAnalyticsContext().traits().anonymousId());
...
Branch.initSession(...);

In the above snippet, this is the Activity context.

I am using react-native-analytics-segment-io, which seems to be the preferred solution for integrating Segment with React Native.

Here are my attempts at implementing this:

iOS

#import "AppDelegate.h"
#import <react-native-branch/RNBranch.h>
+ #import <Analytics/SEGAnalytics.h>
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
+ [RNBranch setRequestMetadataKey:@"$segment_anonymous_id" value:[[SEGAnalytics sharedAnalytics] getAnonymousId]];
  [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];
...
}

The actual segment module is <RNAnalyticsSegmentIO/RNASegmentIO.h>, so maybe that's where I'm going wrong. The app builds correctly with the code above, but closes right after opening.

Android

import io.branch.rnbranch.*;
+ import com.leo_pharma.analytics.AnalyticsPackage;

public class MainActivity extends ReactActivity {

    @Override
    protected void onStart() {
        super.onStart();
+       RNBranchModule.getInstance().setRequestMetadata("$segment_anonymous_id", com.leo_pharma.analytics.AnalyticsPackage.with(this).getAnalyticsContext().traits().anonymousId());
        RNBranchModule.initSession(getIntent().getData(), this);
    }
}

I am unable to get the Android app to build with this, the build logs say error: cannot find symbol (pointing to AnalyticsPackage.with(this)).

Any help or a point in the right direction would be greatly appreciated. Part of me is thinking that this integration may not even be possible since Segment is set up on the JavaScript side of things, and the anonymousId may not be available in time for Branch.

0xpatrickdev avatar Sep 28 '18 20:09 0xpatrickdev

@pcooney10 We will try to reproduce this and see if we can propose a path forward

sequoiaat avatar Sep 28 '18 20:09 sequoiaat

@sequoiaat awesome, thank you. I also opened an issue in react-native-analytics-segment-io as well. The maintainers have been responsive in the past and can hopefully provide some insights here as well.

0xpatrickdev avatar Sep 28 '18 21:09 0xpatrickdev

Hey @sequoiaat or anyone else that may be reading along, is there anyway to use the setRequestMetadataKey or setRequestMetadata method with this lib?

0xpatrickdev avatar Oct 16 '18 19:10 0xpatrickdev

@pcooney10 will try to replicate steps today and post an update

sequoiaat avatar Oct 17 '18 17:10 sequoiaat

@pcooney10 We tried replicate it today but ran into some errors. We try to give you some updates over the weekend

sequoiaat avatar Oct 19 '18 05:10 sequoiaat

Ok thank you @sequoiaat, I appreciate you getting back to me

0xpatrickdev avatar Oct 22 '18 22:10 0xpatrickdev

@pcooney10 @sequoiaat just wondering if you managed to get this working? We're also trying to use the setRequestMetadata call in our app and coming up short with a solution.

mjgaylord avatar Nov 12 '18 16:11 mjgaylord

Hey @sequoiaat, would you mind sharing where you ran into issues / any additional findings you may have? Thanks !

0xpatrickdev avatar Dec 05 '18 15:12 0xpatrickdev

@pcooney10 @mjgaylord Sorry we had tried to replicate it but we ran into some error on linking react native analytic segment io and then we got pulled a bit sideways. We will try to work on this later part of today and share what we find.

sequoiaat avatar Dec 06 '18 19:12 sequoiaat

@pcooney10 @mjgaylord - No luck yet on it at our end to get it working. we will try to work on a path forward for this.

sequoiaat avatar Dec 10 '18 17:12 sequoiaat

Ok thank you for the update @sequoiaat

0xpatrickdev avatar Dec 10 '18 17:12 0xpatrickdev

@pcooney10 - We looked further into this yesterday and reviewed the segment documentation Not sure if it gives you a path forward but here is what we noticed.

Please refer the link https://segment.com/docs/sources/mobile/android/#anonymousid According to this link  with(context).getAnalyticsContext().traits().anonymousId() is applicable to com.segment.analytics.Analytics.

image

  • When we followed the documentation and added “com.segment.analytics.Analytics” instead of ”com.leo_pharma.analytics.AnalyticsPackage”(the segment library’s analytics package path), the app is building.

This is a dependency added to the segment sdk while importing the segment library. So our conclusion is that the irrespective of the libraries we use for segment, we can use Branch.getInstance().setRequestMetadata("$segment_anonymous_id", com.segment.analytics.Analytics.with(this).getAnalyticsContext().traits().anonymousId())

Can you please check this and see if it solves the problem  

sequoiaat avatar Dec 13 '18 17:12 sequoiaat

@sequoiaat I am just seeing your response now - thank you for taking the time to test it out and write it up.

It seems since I first opened this issue, Segment has come out with an official SDK for React Native (link). It has a feature where we can initialize the Segment SDK on the native side of things, so I was thinking this was going to be the best approach.

However, in light of your comments, it seems that this may still work with react-native-analytics-segment-io, so I will try this out as well. Outside of the successful build - were you able to determine if com.segment.analytics.Analytics.with(this).getAnalyticsContext().traits().anonymousId() returned a value, even though Segment is not initiated until a bit later on the JS side of things?

0xpatrickdev avatar Dec 21 '18 00:12 0xpatrickdev

@pcooney10 Did either of your potential fixes listed in your previous comment work to resolve this issue, or are you still experiencing it?

csalmi-branch avatar Jan 04 '19 20:01 csalmi-branch

This has nothing to do with segment, currently setRequestMetadata function isn't exposed from the native code. It's as simple as just adding @ReactMethod annotations and exposing that function from what i can see. I've tried to do this myself and test it but i have no idea how to get it working.

martintreurnicht avatar Feb 05 '19 02:02 martintreurnicht

@csalmi-branch unfortunately I haven't had time to test this out. I still have my suspicions about @sequoiaat's solution if segment is initialized on the js side of things, as we wouldn't have the anonymousId in time.

It seems like it may be possible with segmentio/analytics-react-native, if it's set up on the native side, but I ran into another road block, described in #401, and unfortunately was not provided much color from the Branch dev team.

@martintreurnicht I am not sure it's as simple as exposing a @ReactMethod annotation for setRequestMetadata, as the RNBranch sdk needs to be initialized on the native side of things. And for the setRequestMetadata method in particular, it seems like it needs to be called before initSession() and initSessionWithLaunchOptions. ~I think if the initialization of this library was moved to the JS side, then it could be just as simple as adding a @ReactMethod.~

Edit: Not sure why I said the last part there (now with a strikethrough). Not sure a JS side initialization is possible due to the reliance on the initSessionWithLaunchOptions, openURL, and continueUserActivity methods in iOS (and the android equivalents).

0xpatrickdev avatar Feb 05 '19 17:02 0xpatrickdev

Is anyone still experiencing this issue? Sequoia is no longer looking into it, so if there is anyone running into this issue still, we can have someone with a fresh set of eyes investigate.

csalmi-branch avatar Mar 29 '19 18:03 csalmi-branch

Hi @csalmi-branch, thank you for following up on this topic again.

It seems that @jdee recently picked up on #401, thank you @jdee !

#426 / the 3.0.0 RC seems like it will address the issue, but I can't say for certain without testing it out again. And to echo the original question, we are looking to implement this behavior with react-native-branch: https://docs.branch.io/integrations/segment/#pass-segment-anonymous-id

0xpatrickdev avatar Apr 05 '19 17:04 0xpatrickdev

@pcooney10 I have also ran into this issue currently. The reason why iOS was closing immediately for me was because SEGAnalytics was not initialized/configured. First you would have to configure it on the native side and then you can make the call to get the getAnonymousId. Not sure if your issue is the same as mine, but if you debug in Xcode it lets you know that it was not initialized.

The issue I am trying to solve is making sure that doing a minimal configuration on the native ios/android side with just the write key and then continuing the setup on the react-native side to configure different integrations like amplitude, firebase, etc.

analytics.useNativeConfiguration().setup(...)

Not sure if this would work, but hoping it will. Let me know if you have any tips or learned lessons over the past year. Thanks!

crherman7 avatar Mar 17 '21 14:03 crherman7

Invoking the method setRequestMetadataKey from RNBranch.branch instead of the RNBranch worked for me

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  [RNBranch.branch setRequestMetadataKey:@"$deep_link_url" value:url.absoluteString]; // this line works now
  if (![RNBranch application:app openURL:url options:options]) {
    return YES;
  }
  return [RNBranch application:app openURL:url options:options];
}

This method used to be part of the RNBranch class on previous versions. Maybe something that should be described on the RN docs?

mendes-develop avatar Sep 14 '21 21:09 mendes-develop