react-native: Linking.addEventListener not working: url event never fires
Description
Url event never fires
I followed the indicated setup to handle deep links in react native.
But when I have the app open in background or foreground and I execute command
npx uri-scheme open "mychat://bar" --ios
, url event doesn’t fire.
I saw there is a similar issue in react-navigation, but the fix indicated for AppDelegate.m doesn’t work for me.
Version
0.76
Output of npx react-native info
System: OS: macOS 12.5.1 CPU: (16) x64 Intel® Core™ i9-9880H CPU @ 2.30GHz Memory: 1.30 GB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.18.1 - /usr/local/opt/node@16/bin/node Yarn: 1.22.11 - /usr/local/bin/yarn npm: 8.19.2 - /usr/local/opt/node@16/bin/npm Watchman: Not Found Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 16.0, macOS 12.3, tvOS 16.0, watchOS 9.0 Android SDK: API Levels: 28, 31, 33 Build Tools: 30.0.2, 31.0.0, 33.0.0 System Images: android-31 | Google APIs Intel x86 Atom_64, android-31 | Google Play Intel x86 Atom_64 Android NDK: Not Found IDEs: Android Studio: 2021.2 AI-212.5712.43.2112.8815526 Xcode: 14.0.1/14A400 - /usr/bin/xcodebuild Languages: Java: 13.0.2 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.1.0 => 18.1.0 react-native: 0.70.6 => 0.70.6 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found
Steps to reproduce
clone repo https://github.com/leoparis89/deeplink
- yarn
- cd ios && pod install
- yarn ios
- put app in background
- run command
npx uri-scheme open "mychat://bar" --ios
. App gets focused but url event never fires in./App.js
line 121.
Snack, code example, screenshot, or link to a repository
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 23
Hi @edwardhsueh, I was using react native 0.68.0 and facing the same problem One thing that you can try is adding the below code to the location that specified by React Navigation Documentation as I am not familiar with Swift and placing the code in the wrong location
It’s working for me now
Yes, I do follow the document but still fail. I can’t run in simulator, so I use browser with button to call the url scheme. if app is closed, it works fine. But if app is in background, the url scheme called just bring app to foreground, but the url listener is not fired. My RN is 0.68.2, older than yours. Will this be a problem? By the way, can your app receive url event when it is in background?
if you use
react native +0.71
change
AppDelegate.m
toAppDelegate.mm
I manage to get it work on iOS need to add the url to the xcode setting refer to https://reactnavigation.org/docs/deep-linking/. At xcode, go to Targets, under the Info tab, go to URL Types, add the appID to the identifier and URL Scheme field the appID would be com.RNProject
however my android does not work
I got a build error on android android/app/src/main/java/com/xxx/usermanagement/testapp/MainApplication.java:61: error: cannot find symbol ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); ^ symbol: variable ReactNativeFlipper location: class MainApplication 1 error
I want to add to this issue what I researched, having similar issue:
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
is called, having the path to the file in the launch options under “UIApplicationLaunchOptionsURLKey” key. This path is not accessible (permission-wise to the app). This path is also what you’d get if you call Linking.getInitialURL(BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:...
is called. This method receives a different URL, which is a copy of the file in your app’s temp/inbox folder - fully accessible to your app. And as suggested, it is implemented with one line:return [RCTLinkingManager application:application openURL:url options:options];
, which triggers RCTLinkingManager to send notification via NSNotificationCenter with that (good) url. Now comes the issue: at this point in time, the JS was not yet started and the JS part of the app did not register to listen to “url” event. That is why RCTEventEmitter did not callRCTLinkingManager.startObserving
and the notification with the url is lost. and even if it would have been received, the JS did not register yet, and it would not have been fired to the JS part.Here is how I solved it (and I suggest you implement something more generic/robust for Linking:
when
RCTLinkingManager application:application openURL:url options:options
is called, I save the url in a object’s local variable. the whenRCTLinkingManager.startObserving
is called, if this variable is not nil, I fire the url event.line 19:
static NSString *savedEvent = nil;
at startObserving, at its end:at application:openURL:options
I hope this helps.