facebookarchive / react-native-fbsdk

A React Native wrapper around the Facebook SDKs for Android and iOS. Provides access to Facebook login, sharing, graph requests, app events etc.
https://developers.facebook.com/docs/react-native
Other
2.99k stars 909 forks source link

Deferred Deep App Links #648

Open dancherb opened 4 years ago

dancherb commented 4 years ago

Does this package handle deferred app deep links, e.g. for being able to track events as a result of marketing through facebook?

These are required to be set up in the App Ads Helper when creating ads campaigns, and there's an example of the native code here: https://developers.facebook.com/docs/reference/ios/current/class/FBSDKAppLinkUtility/#fetchDeferredAppLink%253A

fetchDeferredAppLinkData(Context, CompletionHandler)

leotm commented 4 years ago

I'm getting:

Deferred Deep Linking

In order to receive a deep link after install, your app needs to call [FBSDKAppLinkUtility fetchDeferredAppLink:] in the Facebook SDK method when starting up.
Screenshot 2020-04-09 at 00 55 27

I see it here: https://github.com/BranchMetrics/react-native-branch-deep-linking-attribution/blob/d1efbaa9afe877832e5c791ea71f252e873eaddf/ios/RNBranch.m

Also mentioned here: https://github.com/BranchMetrics/react-native-branch-deep-linking-attribution/pull/551

leotm commented 4 years ago

I think we can close and conclude that react-native-fbsdk doesn't address enableFacebookAppLinkCheck but branch.json does for RN like so:

{
  "liveKey": "key_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "testKey": "key_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "enableFacebookLinkCheck": true
}
kurtgn commented 4 years ago

@leotm hey - did you manage to get this to work? I am struggling with the same problem, trying to set up deferred deep linking from FB ads to Android app.

leotm commented 4 years ago

@dancherb I take it back, still getting https://github.com/facebook/react-native-fbsdk/issues/648#issuecomment-611253282 on iOS since going live Thursday with plenty installs, still an issue for you?

@kurtgn Yeah Android's never shown a problem on developers.facebook.com/tools/app-ads-helper.

kurtgn commented 4 years ago

@leotm Thanks! I also have trouble getting my head around about what to do with RN FB SDK. I've also asked Branch directly about this, but got no response so far.

1) What do I do with Facebook SDK? Just install the latest React Native wrapper from https://github.com/facebook/react-native-fbsdk and leave it be, and Branch will take care of the rest?

2) How will Branch give me this deferred deeplink after it gets it from Facebook SDK? Will it be available in branch.subscribe(), or branch.getLatestReferringParams(), or branch.getFirstReferringParams() ?

leotm commented 4 years ago

@kurtgn No problem, have you followed these?

Happy to help you with any particular files

kurtgn commented 4 years ago

@leotm link [1] has some stuff I haven't read, will do that and see if everything is ok. thanks for the links!

kurtgn commented 4 years ago

@leotm No, I think I am still missing something, because deferred deep linking does not work.

Here's what did:

$ cat android/app/src/main/res/values/strings.xml 
<resources>
    <string name="app_name">Invest Advisor</string>
    <string name="facebook_app_id">1807501069529222</string>
    <string name="fb_login_protocol_scheme">fb1807501069529222</string>
</resources>

$ cat android/app/src/main/AndroidManifest.xml 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.investadvisor">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
            android:name=".MainApplication"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:allowBackup="false"
            android:theme="@style/AppTheme">
        <meta-data android:name="com.google.android.gms.ads.AD_MANAGER_APP" android:value="true"/>
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
        <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:launchMode="singleTask"
                android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
                android:windowSoftInputMode="adjustResize">

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>

            <intent-filter>
                <data android:scheme="investadvisor" 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="5joez.app.link"/>
            </intent-filter>

        </activity>

        <!-- Branch init -->
        <meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_xxxxxx"/>
        <meta-data android:name="io.branch.sdk.TestMode" android:value="false"/>

        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
    </application>

</manifest>

Added branch.json:

$ cat android/app/src/main/assets/branch.json 

{
    "debugMode": false,
    "liveKey": "key_live_xxxxx",
    "testKey": "key_test_xxxxxx",
    "useTestInstance": false,
    "delayInitToCheckForSearchAds": true,
    "appleSearchAdsDebugMode": true,
    "enableFacebookLinkCheck": true
}

Now, when I am opening FB App Ads Helper https://developers.facebook.com/tools/app-ads-helper, I see two things I do not understand:

1) It says the app is set up for Android but it is still missing the deferred deep linking feature:

2) When I try to send a deeplink to my app (even not deferred), Facebook says it got an error:

Could you please explain what I am doing wrong?

Could it be because I am running branch.subscribe() not in the beginning of the JS code, but inside the componentDidMount of my main component:


async componentDidMount(): void {

    branch.subscribe((subscribeObj) => {
      logBranchSubscribe(subscribeObj);
    });
    ....
}
kurtgn commented 4 years ago

The FB SDK itself is installed and working, I can see that in the Events manager:

celineotter commented 4 years ago

@kurtgn - please keep us posted, deferred deep link doesn't seem to be not working for me right this moment on either iOS or android. (I don't have a problem with the instant deep link on an installed app when using the branch.io branch.subscribe).

Yox2l commented 4 years ago

Any update on that issue? I'm also trying to use deferred deep link with react-native.

SeanArmstrong commented 3 years ago

I was able to get deferred deep linking working for iOS using code similar to this: https://github.com/UberMC/react-native-fetchDeferredAppLink/blob/master/ios/FBAppLink.m

See the repo README for how to use

I've not tried for Android yet

Yox2l commented 3 years ago

Thanks!

On Fri, 31 Jul 2020 at 14:51 Sean Armstrong notifications@github.com wrote:

I was able to get deferred deep linking working for iOS using code similar to this:

https://github.com/UberMC/react-native-fetchDeferredAppLink/blob/master/ios/FBAppLink.m

See the repo README for how to use

I've not tried for Android yet

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/facebook/react-native-fbsdk/issues/648#issuecomment-667081718, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACMGVMP4ZDHGU56NXLAE743R6KV3XANCNFSM4I4AORSQ .

-- יותם לייכטר Yotam Lichter

       GSM +972 (0)52 8314153
Maftalion commented 3 years ago

Has anyone gotten this to work without needing Branch? fetchDeferredAppLink is successfully getting the url, but my event listener isn't picking up on the url Linking.addEventListener('url', ...)

EDIT: Ended up doing the approach above, created native modules to programmatically call the fetch instead of relying on the listener.

imwexpex commented 3 years ago

Has anyone gotten this to work without needing Branch? fetchDeferredAppLink is successfully getting the url, but my event listener isn't picking up on the url Linking.addEventListener('url', ...)

EDIT: Ended up doing the approach above, created native modules to programmatically call the fetch instead of relying on the listener.

Hi! Can you please publish native module? I think it would be useful for a lot of users

Maftalion commented 3 years ago

Has anyone gotten this to work without needing Branch? fetchDeferredAppLink is successfully getting the url, but my event listener isn't picking up on the url Linking.addEventListener('url', ...) EDIT: Ended up doing the approach above, created native modules to programmatically call the fetch instead of relying on the listener.

Hi! Can you please publish native module? I think it would be useful for a lot of users

hey, will try if I have time but basically if you look up how to create native modules you can just use this:

// Android
public class DeferredDeepLink extends ReactContextBaseJavaModule {

  public DeferredDeepLink(ReactApplicationContext reactContext) {
    super(reactContext);
  }
   @Override
  public String getName() {
    return "DeferredDeepLink";
  }

  @ReactMethod
  public void fetchUrl(final Promise promise) {
    try {
      AppLinkData.fetchDeferredAppLinkData(getReactApplicationContext(),
        new AppLinkData.CompletionHandler() {
          @Override
          public void onDeferredAppLinkDataFetched(AppLinkData appLinkData) {
              if (appLinkData != null){
                promise.resolve(appLinkData.getTargetUri().toString());
              } else {
                promise.resolve(null);
              }
          }
      });
    } catch (Exception e) {
        promise.reject("500", e.getMessage(), e);
    }
  }
} 
// ios
@implementation DeferredDeepLink

RCT_EXPORT_MODULE();

RCT_REMAP_METHOD(fetchUrl,
                 resolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *url, NSError *error) {
      if (error) {
        reject(@"error", @"error fetching deferred deeplink", error);
      }
      if (url) {
        NSString* appLink = [NSString stringWithFormat:@"%@", url];
        resolve(appLink);
      }
      resolve(nil);
    }];
  });
}

@end

then in your app...

    const url = await NativeModules.DeferredDeepLink.fetchUrl();
    if (url) {
      // do logic with url
    }
imwexpex commented 3 years ago

Has anyone gotten this to work without needing Branch? fetchDeferredAppLink is successfully getting the url, but my event listener isn't picking up on the url Linking.addEventListener('url', ...) EDIT: Ended up doing the approach above, created native modules to programmatically call the fetch instead of relying on the listener.

Hi! Can you please publish native module? I think it would be useful for a lot of users

hey, will try if I have time but basically if you look up how to create native modules you can just use this:

// Android
public class DeferredDeepLink extends ReactContextBaseJavaModule {

  public DeferredDeepLink(ReactApplicationContext reactContext) {
    super(reactContext);
  }
   @Override
  public String getName() {
    return "DeferredDeepLink";
  }

  @ReactMethod
  public void fetchUrl(final Promise promise) {
    try {
      AppLinkData.fetchDeferredAppLinkData(getReactApplicationContext(),
        new AppLinkData.CompletionHandler() {
          @Override
          public void onDeferredAppLinkDataFetched(AppLinkData appLinkData) {
              if (appLinkData != null){
                promise.resolve(appLinkData.getTargetUri().toString());
              } else {
                promise.resolve(null);
              }
          }
      });
    } catch (Exception e) {
        promise.reject("500", e.getMessage(), e);
    }
  }
} 
// ios
@implementation DeferredDeepLink

RCT_EXPORT_MODULE();

RCT_REMAP_METHOD(fetchUrl,
                 resolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *url, NSError *error) {
      if (error) {
        reject(@"error", @"error fetching deferred deeplink", error);
      }
      if (url) {
        NSString* appLink = [NSString stringWithFormat:@"%@", url];
        resolve(appLink);
      }
      resolve(nil);
    }];
  });
}

@end

then in your app...

    const url = await NativeModules.DeferredDeepLink.fetchUrl();
    if (url) {
      // do logic with url
    }

Thanks for a such quick response! I've written the same code, but when I'm testing with Facebook's helper in dev-mode i don't receive Deferred link. Is it ok, and will it work in production from Google Play? Thanks in advance!

Maftalion commented 3 years ago

Are you testing android or ios? what I do to test:

  1. uninstall app
  2. send link via https://developers.facebook.com/tools/app-ads-helper (make sure deferred is checked)
  3. click notification on phone logged in with same fb user (should open to app store)
  4. instead of downloading through app store, build directly to phone

If you're getting null, I heard logging out/in on fb app on your phone might solve it

imwexpex commented 3 years ago

Are you testing android or ios? what I do to test:

  1. uninstall app
  2. send link via https://developers.facebook.com/tools/app-ads-helper (make sure deferred is checked)
  3. click notification on phone logged in with same fb user (should open to app store)
  4. instead of downloading through app store, build directly to phone

If you're getting null, I heard logging out/in on fb app on your phone might solve it

My app isn't in PlayStore yet, so, maybe it's the reason. But i'm doing the same way as you say.

Will try to log out/in hack

Maharshi01 commented 3 years ago

Are you testing android or ios? what I do to test:

  1. uninstall app
  2. send link via https://developers.facebook.com/tools/app-ads-helper (make sure deferred is checked)
  3. click notification on phone logged in with same fb user (should open to app store)
  4. instead of downloading through app store, build directly to phone

If you're getting null, I heard logging out/in on fb app on your phone might solve it

Hey @Maftalion, What's the reason behind this? Screenshot 2020-09-22 at 4 43 07 PM FYI : Deferred Deeplinking is working fine for android.

Maftalion commented 3 years ago

@Maharshi01 reason for what? these are the steps for how I test deferred deeplink during development & making sure you actually get a url (not null)

Maharshi01 commented 3 years ago

Hey @Maftalion, What i meant was i have integrated native code for deferred deeplinking and i called the method from my react native component. For android , i can get the deferred deep link but for iOS in facebook app-ads-helper under "iOS setup" it is still showing that Deferred Deep Linking is not setup(refer the image which i have uploaded earlier) even though i am calling the method(as of now iam getting null when i call the method). Can you please tell me what is the issue?

DanGDroid commented 3 years ago

did somone test lates version? v3.0.0 says it added fetch deffered data after install #813