klaviyo / klaviyo-react-native-sdk

MIT License
4 stars 3 forks source link

Linking.getInitialURL() always returning null in IOS when notification open the app #140

Closed youcefswoo closed 4 months ago

youcefswoo commented 5 months ago

Checklist

Description

After following the documentation and the example in the repository, I began testing to see if I could receive the deep link when the app is killed. In Android, it works well, but in iOS, Linking.getInitialURL() always returns null.

Expected behavior

I expected to receive the deep link that I placed in the deep link section of the notification definition.

Actual behavior

Linking.getInitialURL() always returns null in iOS when a notification is clicked.

Steps to reproduce

1. Create a notification with a deep link for IOS.
2. Click on the notification to open the application.

The Klaviyo React Native SDK version information

0.3.0

Environment Description

Using real device (iPhone 12 . IOS 16.6.1) react native 0.73.3

ajaysubra commented 5 months ago

@youcefswoo Couple questions -

  1. Can you confirm that you followed the instructions from the readme?
  2. Are you able to reproduce this issue using the example app here?

When we published the example iOS app, we tested and deep linking was working but does involve some intricate setup for iOS outlined in the readme.

youcefswoo commented 5 months ago

@youcefswoo Couple questions -

  1. Can you confirm that you followed the instructions from the readme?
  2. Are you able to reproduce this issue using the example app here?

When we published the example iOS app, we tested and deep linking was working but does involve some intricate setup for iOS outlined in the readme.

@ajaysubra

  1. Yes, I took all the time to follow the instructions and I double-checked all the steps multiple times. For the options, I used the first one since it is faster and easier.
  2. Yes, I executed the example. I only changed the Bundle Identifier to match the bundle existing in my Klaviyo account so I can receive the notification. I created some test campaigns with rntest:// as a deep link. When I click the notification, it opens the app, but I always get null from getInitialURL.
kennyklaviyo commented 5 months ago

@youcefswoo You mention getInitialURL() returning null, is your app in the background when you're clicking on the push notification? Or is the app killed when you click on the push notification? The README points out another method%3B) of getting the deep link: Linking.addEventListener(...). Have you looked at what that returns?

youcefswoo commented 5 months ago

@youcefswoo You mention getInitialURL() returning null, is your app in the background when you're clicking on the push notification? Or is the app killed when you click on the push notification? The README points out another method%3B) of getting the deep link: Linking.addEventListener(...). Have you looked at what that returns?

In all my tests, the app was killed. The addEventListener is used for real-time clicks when the app is in the background or foreground. However, when the app is killed, the only way to retrieve the deep link that triggers the app to open is by using getInitialURL().

ajaysubra commented 5 months ago

@youcefswoo I just tested using the example app using both option 1 and 2. With option 1, the application delegate application(_:open:options) is correctly getting called and as for option 2 I am seeing the SDK correctly calling the callback passed when you call the handle method on iOS. Outside of this, our SDK doesn't do anything as it pertains to deep linking. Some options that I would debug are,

  1. Be sure that the installation step 2 from the iOS example appedelegate is done in your app and that you are not passing in the deepLinkHandler when calling the SDK handle method. If you pass in the deepLinkHandler that will be called and the application delegate application(_:open:options) will not.
  2. If the above is setup correctly, I would add a print statement in application(_:open:options) and see if the url is being printed there.

Please try these out and let us know.

youcefswoo commented 5 months ago

@ajaysubra I managed to reproduce the issue in the latest version of example project, as mentioned above. Therefore, I don't believe the issue is related to my configuration. I just want to confirm whether you tested the process with a real Klaviyo notification, or if you simply clicked on a deep link, or if you executed this command: npx uri-scheme open "MY_DEEP_LINK" --ios.

ajaysubra commented 5 months ago

Hey @youcefswoo I missed the part about the app being killed when you receive the push notification when testing yesterday. Sorry about that. I will look into this today and get back to you.

ajaysubra commented 5 months ago

Hey @youcefswoo You were right, when the example iOS app is killed and a push deep link is received the getInitialURL is printing null. It's not clear what is causing this, as far as the iOS side is concerned, application(_:open:options) is getting called when a push is received and from that point onwards it's up to RCTLinkingManager to call the appropriate callback on the react native side.

We will look into this further and get back to you.

chinleung commented 5 months ago

Hey @ajaysubra,

Do you have any update or ETA for the issue here? 😄

ajaysubra commented 5 months ago

@chinleung Unfortunately no updates yet. Should have an update by end of next week. Appreciate the patience.

chinleung commented 5 months ago

@chinleung Unfortunately no updates yet. Should have an update by end of next week. Appreciate the patience.

Perfect, thanks for the update!

ajaysubra commented 4 months ago

Hey @youcefswoo @chinleung: After doing some digging turns out this is an issue with react native. There are many open issues on their Github issues page but this is the most recent one. The best explanation I found of the issue was this. I tried several of the workaround but many of them are for older versions of react native and no longer valid, but one workaround that I retro fitted to newer versions of react native was to add the key UIApplicationLaunchOptionsURLKey to the launch arguments before calling super method in application:didFinishLaunchingWithOptions:. This approach worked and calls the react native initial url listener!

I created a PR that demonstrates this fix and updated the troubleshooting guide for reference here. Please try it out and let me know how it goes. Thanks!

youcefswoo commented 4 months ago

@ajaysubra I integrated the solution from the PR, and it works in all phone states. Thank you for your support.

ajaysubra commented 4 months ago

Perfect. Closing this issue now!

ajaysubra commented 4 months ago

Hey, just FYI - I added a note here as to why this workaround works.