appsflyer-react-native-plugin icon indicating copy to clipboard operation
appsflyer-react-native-plugin copied to clipboard

[iOS] Deep link handlers not called when app is fully closed

Open lucasroca opened this issue 4 years ago • 85 comments

Plugin Version

6.1.20

On what Platform are you having the issue?

iOS

What did you do?

Installed the latest version of the plugin

What did you expect to happen?

onDeepLink to be called

What happened instead?

The handler wasn't triggered

Please provide any other relevant information.

On iOS, react-native-appsflyer version 6.1.10, when clicking a OneLink the app opens butonAppOpenAttribution is not triggered when the app is fully closed.

Then I upgraded to react-native-appsflyer version 6.1.20 to test unified links. Again, onDeepLink works on every case except when the app is installed but fully closed and I open a OneLink.

I tried both on simulator and real device with no luck.

lucasroca avatar Dec 14 '20 07:12 lucasroca

Also problem, please fix this bag

goldqwert avatar Dec 14 '20 15:12 goldqwert

Same problem here

Plugin 6.1.20 React Native 0.63.3

Appears only on iOS, on Android works as expected.

Voidozzer avatar Dec 16 '20 13:12 Voidozzer

Hi @amit-kremer93, do you have any updates on this?

lucasroca avatar Dec 17 '20 08:12 lucasroca

Did you follow this?? For now, you can use onInstallConversionData listener to handle direct deep link in iOS by checking if is_first_launch === false. it's not the best solution but it will work until we figure it out

amit-kremer93 avatar Dec 20 '20 09:12 amit-kremer93

onInstallConversionData is not enough to get all the params. I had to downgrade to 6.0.50 to restore the behaviour :(

rborn avatar Dec 22 '20 18:12 rborn

onInstallConversionData is not enough to get all the params. I had to downgrade to 6.0.50 to restore the behaviour :(

6.0.50 - does not handled when the app is turned on :( latest version - handled when app on, but not handled when start :(

can developers combine these 2 functions?

or maybe add in onInstallConversionData all params?

goldqwert avatar Dec 29 '20 10:12 goldqwert

@Goldyukol in which type of deep link do you use? URL scheme or universal link? 6.0.50 works fine for me when the app in the background and when fully closed

amit-kremer93 avatar Dec 31 '20 09:12 amit-kremer93

@amit-kremer93 how does it work for you ? we use appsflyer links

rborn avatar Jan 05 '21 16:01 rborn

@Goldyukol in which type of deep link do you use? URL scheme or universal link? 6.0.50 works fine for me when the app in the background and when fully closed

In latest version this features doesn't work

goldqwert avatar Jan 06 '21 07:01 goldqwert

Did you follow this?? For now, you can use onInstallConversionData listener to handle direct deep link in iOS by checking if is_first_launch === false. it's not the best solution but it will work until we figure it out

Yes, I've followed those steps. The issue still remains. As mentioned by @rborn, using onInstallConversionData doesn't help much.

@Goldyukol in which type of deep link do you use? URL scheme or universal link? 6.0.50 works fine for me when the app in the background and when fully closed

I'm using universal links.

lucasroca avatar Jan 08 '21 14:01 lucasroca

@amit-kremer93 like the rest of us here, definitely still happening on my end.

On relaunching the app, onAppOpenAttribution doesn't happen, but if it was running in the background, direct deep links would successfully trigger it.

csantarin avatar Jan 13 '21 07:01 csantarin

It seems like the issue started after the native SDK was upgraded and we are working on a solution. Sorry for the inconvenience.

amit-kremer93 avatar Jan 14 '21 06:01 amit-kremer93

I released a new version (6.1.40) with a fix for the onAppOpenAttribution in iOS. The implementation has slightly changed so please see this but the flow is the same. Please let us know here if there is any problem. thanks!

amit-kremer93 avatar Jan 17 '21 13:01 amit-kremer93

Update

Those who are running into this might find https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin/issues/223#issuecomment-768371228 useful.

Reasoning here and here.


Please let us know here if there is any problem.

@amit-kremer93 Yup, unfortunately, there is one.

I opened the app from the phone's email client. Then shortly after, the app crashed before it could even start logging anything to the JavaScript console. Here's the native log. ML.Debug refers to my local app process.

default	12:17:28.772654+0800	ML.Debug	[DEBUG] AppsFlyer: [HTTP] 
Result: {
    data = {length = 4, bytes = 0x226f6b22};
    dataStr = "\"ok\"";
    retries = 2;
    statusCode = 200;
    taskIdentifier = 3;
}                
Error: (null)
default	12:17:28.772732+0800	ML.Debug	[DEBUG] AppsFlyer: Loading conversion data
default	12:17:28.773572+0800	ML.Debug	[DEBUG] AppsFlyer: [GCD-A02] -[RNAppsFlyer onConversionDataSuccess:]:
{
    "af_message" = "organic install";
    "af_status" = Organic;
    "install_time" = "2021-01-18 04:06:20.689";
    "is_first_launch" = 0;
}
default	12:17:28.775784+0800	ML.Debug	[DEBUG] AppsFlyer: [CACHE] Deleting file: /var/mobile/Containers/Data/Application/1E631D5D-803D-4A15-8B56-FA65694DFF2D/Library/Caches/appsflyer-v1/632636244.2472.plist
default	12:17:28.775850+0800	ML.Debug	[DEBUG] AppsFlyer: [HTTP] Dealloc. Time elapsed for: `160-1610943444.211549` - 3.944231986999512
default	12:18:09.942508+0800	ML.Debug	*** Assertion failure in -[RCTEventEmitter sendEventWithName:body:](), /Users/csantarin/moneylion/mobile-app/node_modules/react-native/React/Modules/RCTEventEmitter.m:50
default	12:18:10.253181+0800	ML.Debug	*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onAttributionFailure with body: {"status":"failure","type":"onAttributionFailure","data":"Authentication Failed"}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in RNAppsFlyer, even though it's inherited from RCTEventEmitter.'
*** First throw call stack:
(0x1853619d8 0x1996cab54 0x18527050c 0x1865b9238 0x1051ecf80 0x1058948a8 0x1058946c8 0x186657614 0x1852e1bf0 0x1852e1af0 0x1852e0e38 0x1852db3e0 0x1852daba0 0x19c018598 0x187bca3d8 0x187bcf958 0x104604564 0x184fb9568)

csantarin avatar Jan 18 '21 05:01 csantarin

@csantarin {"status":"failure","type":"onAttributionFailure","data":"Authentication Failed"} means that you have an issue with your devKey. about the crash, i released an hot fix.

amit-kremer93 avatar Jan 18 '21 11:01 amit-kremer93

@amit-kremer93 , I'm testing version 6.1.41

  • On android: it works in either scenarios, when app is in background, or when it's fully closed.
  • On ios: it doesn't work if app is fully closed. It works if app is in background.

I already updated didFinishLaunchingWithOptions.

haipham-kontist avatar Jan 18 '21 12:01 haipham-kontist

@ amit-kremer93 , тестирую версию6.1.41

  • На Android: он работает в любом сценарии, когда приложение находится в фоновом режиме или когда оно полностью закрыто.
  • На ios: не работает, если приложение полностью закрыто. Работает, если приложение находится в фоновом режиме.

Я уже обновился didFinishLaunchingWithOptions.

How you updated didFinishLaunchingWithOptions?

Send code pls

goldqwert avatar Jan 18 '21 12:01 goldqwert

How you updated didFinishLaunchingWithOptions?

Send code pls

You can find it in the updated guide: https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin/blob/master/Docs/Guides.md#import

  if(_AppsFlyerdelegate == nil){
    _AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
  }
  [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];

haipham-kontist avatar Jan 18 '21 12:01 haipham-kontist

@amit-kremer93 , I'm testing version 6.1.41

  • On android: it works in either scenarios, when app is in background, or when it's fully closed.
  • On ios: it doesn't work if app is fully closed. It works if app is in background.

I already updated didFinishLaunchingWithOptions.

  [[FBSDKApplicationDelegate sharedInstance] application:application
    didFinishLaunchingWithOptions:launchOptions];

added after?

  if(_AppsFlyerdelegate == nil){
    _AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
  }
  [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];

goldqwert avatar Jan 18 '21 12:01 goldqwert

I released a new version (6.1.40) with a fix for the onAppOpenAttribution in iOS. The implementation has slightly changed so please see this but the flow is the same. Please let us know here if there is any problem. thanks!

Problem is not resolved

goldqwert avatar Jan 18 '21 12:01 goldqwert

Update

Those who are running into this might find https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin/issues/223#issuecomment-768371228 useful.

Reasoning here and here.


@Goldyukol not-maintainer here. On 6.1.41, I imagine it should look like this on a brand new AppDelegate.m:

#import <RNAppsFlyer.h>
#import <React/RCTLinkingManager.h>
#import <AppsFlyerLib/AppsFlyerLib.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Flipper init here...

  if(_AppsFlyerdelegate == nil){
    _AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
  }
  [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];

  // React Native Bridge and Root View init here...
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] 
    initWithBridge:bridge
    moduleName:@"FiftyViewsUnderTheAppiumSea"
    initialProperties:nil
  ];

  // More on React Native Bridge and Root View init here...

  return YES;
}

Correct me if I'm wrong, @amit-kremer93. That's how I'm initializing the SDK on my end.

csantarin avatar Jan 18 '21 16:01 csantarin

{"status":"failure","type":"onAttributionFailure","data":"Authentication Failed"} means that you have an issue with your devKey. about the crash, i released an hot fix.

Right you are, @amit-kremer93. But I've followed the iOS SDK / RN plugin integration guide. The devKey and appId are correct. So, I don't get it. Why would I have this issue?

On my end, .initSdk(config) is called right after subscribers, i.e. onInstallConversionData, onAppOpenAttribution, etc.

csantarin avatar Jan 18 '21 16:01 csantarin

@amit-kremer93 we are also experiencing a similar issue. On the latest version of the plugin (6.1.41) for iOS: if the app is fully closed, after tapping a onelink in the phones email client, the phone crashes with the following error

[DEBUG] AppsFlyer:                        
[Shortlink] OneLink:(null)                       
[Shortlink] Response Info:{
    data = {length = 21, bytes = 0x41757468656e7469636174696f6e204661696c6564};
    dataStr = "Authentication Failed";
    retries = 0;
    statusCode = 401;
    taskIdentifier = 1;
}                       
[Shortlink] Error: Error Domain=com.appsflyer.sdk.serialize Code=61 "Authentication Failed" UserInfo={NSLocalizedDescription=Authentication Failed}

Everything is setup according to the docs and was not crashing before updating the plugin (although onDeepLink was not firing on iOS). I have made the recommended changes from the new readme to the AppDelegate.m as well.

If the app is in the background, it works as expected i.e. the onDeepLink handler is called and no crash.

jwebcat avatar Jan 19 '21 20:01 jwebcat

Same here, if i open the app and then i use deep link it works, but when the app is completely closed does not work :(

colaquecez avatar Jan 20 '21 03:01 colaquecez

@colaquecez @jwebcat @Goldyukol @haipham-kontist @lucasroca @Voidozzer @rborn

I found something with the help of their support team that might help you out.

  • react-native-appsflyer 6.1.41
  • AppsFlyerFramework 6.1.3
  if(_AppsFlyerdelegate == nil){
    _AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
  }
  [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
+  [AppsFlyerLib shared].appsFlyerDevKey = @"YOUR_APPSFLYER_DEV_KEY";

For the app I work with, this is sorely needed, on top of the initSdk() params. This isn't mentioned in the docs, though.

@amit-kremer93 I feel like this is a hack, but it holds for the time being. Would it be possible to remedy this gotcha or at least make it known to everyone in the Init SDK guide?


@amit-kremer93 The crash that I mentioned in https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin/issues/223#issuecomment-761987345 is no longer there. There was a remnant code lying about (from AppsFlyerFramework 4.10.x days) in AppDelegate.m > application:applicationDidBecomeActive that had to be removed from our codebase as it was causing all of those crashes:

(void)applicationDidBecomeActive:(UIApplication *)application {
  // Don't need the below.
-  [[AppsFlyerLib shared] start];

csantarin avatar Jan 27 '21 09:01 csantarin

@csantarin I feel like this is a hack, but it holds for the time being. Would it be possible to remedy this gotcha or at least make it known to everyone in the Init SDK guide? yes, you are right this is a workaround for now. it happened because of some improvements in the iOS SDK that launches faster than the plugin in react-native so we working on a long-term fix.

amit-kremer93 avatar Jan 27 '21 13:01 amit-kremer93

@csantarin thanks a lot for this. could you please explain where to put the code above? Because I don't have anything similar to this in my appdelegate 🤗

  if(_AppsFlyerdelegate == nil){
    _AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
  }
  [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
+  [AppsFlyerLib shared].appsFlyerDevKey = @"YOUR_APPSFLYER_DEV_KEY";

rborn avatar Jan 27 '21 14:01 rborn

@rborn assuming latest React Native, in application:didFinishLaunchingWithOptions:

AppDelegate.m

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>

// AppsFlyer imports
#import <RNAppsFlyer.h>
#import <AppsFlyerLib/AppsFlyerLib.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Flipper init here...


  // AppsFlyer init here...
  if(_AppsFlyerdelegate == nil){
    _AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
  }
  [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
  [AppsFlyerLib shared].appsFlyerDevKey = @"YOUR_APPSFLYER_DEV_KEY"; // HACK: iOS SDK is faster than RN plugin


  // React Native Bridge and Root View init here...
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] 
    initWithBridge:bridge
    moduleName:@"FiftyViewsUnderTheAppiumSea"
    initialProperties:nil
  ];

  // More on React Native Bridge and Root View init here...

  return YES;
}

Like in https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin/issues/223#issuecomment-762352475, except you now have:

[AppsFlyerLib shared].appsFlyerDevKey = @"YOUR_APPSFLYER_DEV_KEY";

It's also in the docs. Check it out.

csantarin avatar Jan 27 '21 15:01 csantarin

@amit-kremer93 @rborn I have implemented the hacky workaround for plugin version 6.1.41 and now the onDeepLink handler is called and the app no longer crashes. There seems to be a new issue introduced however, the onDeepLink handler is not called intermittently both with the app fully closed and in the background. It works about 80% of the time. This makes me think perhaps a race condition is introduced with this latest workaround. This was tested on physical devices (iOS 13.1.2 and 14.4) Is this happening for anyone else?

In the code below af_dp replaced with xxx

When the Onelink works and calls the onDeepLink handler the native logs show:
[DEBUG] AppsFlyer:                        
[Shortlink] OneLink:{
    "af_dp" = "xxx";
    "deep_link_value" = myProgram;
    "media_source" = Email;
    pid = Email;
}                       
[Shortlink] Response Info:{
    data = {length = 90, bytes = 0x7b227069 64223a22 456d6169 6c222c22 ... 22456d61 696c227d };
    dataStr = "{\"pid\":\"Email\",\"deep_link_value\":\"myProgram\",\"af_dp\":\"xxx\",\"media_source\":\"Email\"}";
    retries = 0;
    statusCode = 200;
    taskIdentifier = 5;
}                       
[Shortlink] Error: (null)

followed by

[DEBUG] AppsFlyer: [GCD-A02] -[RNAppsFlyer onConversionDataSuccess:]:
{
    "af_message" = "organic install";
    "af_status" = Organic;
    "install_time" = "2021-01-27 21:51:15.073";
    "is_first_launch" = 0;
}
When the Onelink doesn't work and fails to call onDeepLink handler, the native logs only show:
[DEBUG] AppsFlyer:                        
[Shortlink] OneLink:{
    "af_dp" = "xxx";
    "deep_link_value" = myProgram;
    "media_source" = Email;
    pid = Email;
}                       
[Shortlink] Response Info:{
    data = {length = 90, bytes = 0x7b227069 64223a22 456d6169 6c222c22 ... 22456d61 696c227d };
    dataStr = "{\"pid\":\"Email\",\"deep_link_value\":\"myProgram\",\"af_dp\":\"xxx\",\"media_source\":\"Email\"}";
    retries = 0;
    statusCode = 200;
    taskIdentifier = 5;
}                       
[Shortlink] Error: (null)

In this case [RNAppsFlyer onConversionDataSuccess:]: is never called and it fails to call either the onInstallConversionData or onDeepLink handlers.

With the plugin version 6.1.20 it calls the onDeepLink handler successfully every time you tap a Onelink when the app is in the foreground, but is not called when the app is fully closed.

jwebcat avatar Jan 27 '21 22:01 jwebcat

I am also having this issue in version 6.1.41. onDeepLink is only called if the app is already open. I have tried everything above including the "hack" from @csantarin, and it still does not work.

I have tried on simulator and real device.

What else can I try?

curiousdustin avatar Jan 29 '21 00:01 curiousdustin