Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deep link is not working in ios, react native 0.71 #157

Closed
vanenshi opened this issue Jun 23, 2023 · 11 comments
Closed

Deep link is not working in ios, react native 0.71 #157

vanenshi opened this issue Jun 23, 2023 · 11 comments

Comments

@vanenshi
Copy link

SDK version: 2.4.2

Environment: Development

Are logs available? No

Describe the bug
The instructions in this link are for react native version 70. and in the 71 they totally change the didFinishLaunchingWithOptions. without this fix, deep links not working at all, and the following code never get called:

- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
 {
   return [RCTLinkingManager application:application openURL:url options:options];
 }

To Reproduce

  1. setup the push notification based on the docs
  2. confirm that the rich push notification is working (image is getting sent)
  3. confirm that deep link is working locally
  4. press on the notification (app in the background, or killed), and the application doesn't lunch the deep link page

Additional context
this is the current code in react native 0.71

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [FIRApp configure];
  self.moduleName = @"Roombadi";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};
  
  // Set FCM messaging delegate
  [FIRMessaging messaging].delegate = self;
  // [CIO] Call this before  calling registerPushNotification:self
  [pnHandlerObj initializeCioSdk];
  // [CIO] Register for remote push when the app starts
  [pnHandlerObj registerPushNotification:self];
  
  [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
  
  [RNBootSplash initWithStoryboard:@"BootSplash" rootView:self.window.rootViewController.view]; // <- initialization using the storyboard file name
  
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@ami-aman
Copy link
Collaborator

Hi @vanenshi

We apologize for any inconvenience caused and appreciate you bringing this issue to our attention. We want to assure you that we are taking this matter seriously. Our team will conduct an internal investigation to determine the root cause of the issue and work towards resolving it. We will provide you with an update as soon as we have more information.

In the meantime, please feel free to provide any additional information or details that you believe would be helpful in addressing this problem.

@djw27
Copy link

djw27 commented Jun 28, 2023

I'd just like to add that I am also experiencing this issue - I've been in touch with support via email for a couple of weeks now and still can't get to the bottom of what's going on.

Similar to @vanenshi we're able to validate that the payload received by the app contains the nested CIO data with a link correctly:
Screenshot 2023-06-27 at 13 18 30

And we're able to validate that clicking a deep link on device correctly triggers openURL to be called and redirects to the correct route in the app, but clicking a push notification from CustomerIO results in the native openURL method not being called.

@vanenshi can you add any clarity over what changes between 0.70 -> 0.71 you're referring to which might be coming in to play here?

@vanenshi
Copy link
Author

@djw27 Yes, we already had this feature working in version 2.0.0 and react native 70 (iOS)

I am guessing that something break the deep like when we upgrade the package and react native

@levibostian
Copy link
Contributor

Thanks for reporting this to us, @vanenshi. We are in the process of reproducing this issue ourselves and will get back to you on a fix.

@levibostian
Copy link
Contributor

levibostian commented Jun 30, 2023

Thank you again for reporting this issue to us.

We have been able to reproduce the issue in a React Native app (without any 3rd party push dependencies installed) and did some debugging of the Customer.io SDK. We have identified some ways that we could improve this issue of handling deep links when the app is killed/closed.

It seems as though handling of deep links when an app is killed is a known and common problem in React Native with various ways to solve the problem.

We are going to talk as a team to figure out how we would like to help customers around this limitation. In the mean time, I suggest reviewing what other React Native developers are doing to get around this issue.

Your AppDelegate looks good as far as Customer.io SDK push setup. Therefore, I am thinking that your issue could be more of a React Native deep link issue then an issue with our SDK. I do understand that our documented workaround is not up-to-date to React Native 71. Unfortunately, I don't have an updated workaround at this time for 71.

@djw27
Copy link

djw27 commented Jul 4, 2023

@vanenshi we are running RN 0.71 and have something like the following in our didFinishLaunchingWithOptions which seems to work:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"main";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};

  ...

  // Set FCM messaging delegate
  [FIRMessaging messaging].delegate = self;
  // [CIO] Call this before  calling registerPushNotification:self
  [pnHandlerObj initializeCioSdk];
  // [CIO] Register for remote push when the app starts
  [pnHandlerObj registerPushNotification:self];
  
  NSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];
    if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
        NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
        if (pushContent[@"CIO"] && pushContent[@"CIO"][@"push"] && pushContent[@"CIO"][@"push"][@"link"]) {
          NSString *initialURL = pushContent[@"CIO"][@"push"][@"link"];
            if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {
                modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];
            }
        }
    }
  
  // Replace `launchOptions` parameter with `modifiedLaunchOptions` calculated above
  return [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];
}

@djw27
Copy link

djw27 commented Jul 7, 2023

@vanenshi final update from me on this - we realised that we were running into this issue because we had the notifee library installed, which we were using for 'local' push notifications (scheduled prompts etc)

This may or may not be the case for you (another Push Notification library installed) - but may help any future readers.

We ended up with something similar to this:


const linking = {
  prefixes,

  // ...

  subscribe(listener) {
    // Listen to incoming links from Notifee - Notifee 'overrides' events coming from
    // customer io
    const unsubscribeNotifeeForeground = notifee.onForegroundEvent(async ({ detail, type }) => {

      CustomerIO.pushMessaging()
        .onMessageReceived(detail, false)
        .then(handled => {
          // ...
        });

      if (type === EventType.PRESS) {
        // N.B. The below case is very specific to using notifee
        //
        // If we're receiving an event as the result of a notification press launching the app,
        // and if a URL has been extracted from the notification, then do nothing here as this
        // should be handled in our `getInitialURL` handler
        const url = await Linking.getInitialURL();
        if (url != null) return;

        const { notification } = detail;

        if (isCIONotification(notification?.data)) {
          if (notification?.data?.CIO?.push?.link) {
            listener(notification?.data?.CIO?.push?.link);
          }
        }
      }
    });

    // Listen to incoming links from deep linking
    const linkingSubscription = Linking.addEventListener('url', ({ url }) => {
      listener(url);
    });

    return () => {
      unsubscribeNotifeeForeground();
      linkingSubscription.remove();
    };
  },
};

@vanenshi
Copy link
Author

vanenshi commented Jul 7, 2023

@djw27
Actually, that was the case for us too 😂
Thanks dan, you helped us a lot

@berkcoker
Copy link

berkcoker commented Nov 20, 2023

If CustomerIO came with local notifications, we'd switch to completely using CustomerIO. Dropping this here as feedback, but I recognize that it might not be a small feat to implement that :)

@ami-aman
Copy link
Collaborator

ami-aman commented Aug 5, 2024

Thank you all for your feedback and insights.

This issue arises due to lifecycle differences between React Native and the native module when the app is in a killed state. We have documented this issue along with a workaround in our troubleshooting guide here.

I am closing this ticket for now. Please feel free to add new comments or reopen it if needed. We would be happy to help.

@ami-aman ami-aman closed this as completed Aug 5, 2024
@vanenshi
Copy link
Author

vanenshi commented Aug 5, 2024

Thanks guys, aside from the problem you mentioned, we also had another problem that I also fixed in the boilerplate we used. I'll leave the PR here for anybody needs it

infinitered/ignite#2679

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants