react-native: React native deep linking not working when app is in background state
š Bug Report
When the app is closed, I am able to get deep link url that is clicked by Linking.getInitialURL(). When the app is in the background state, then nothing is mounted. So, I am not able to get the url even by the Linking.addEventListener(āurlā, method_name).
What is the way to achieve this?
To Reproduce
Expected Behavior
Code Example
componentDidMount() { Linking.addEventListener(āurlā, this._handleOpenURL); }, componentWillUnmount() { Linking.removeEventListener(āurlā, this._handleOpenURL); }, _handleOpenURL(event) { console.log(event.url); } I have added this code in app.js
Environment
React Native Environment Info: System: OS: Linux 4.15 Ubuntu 18.04.1 LTS (Bionic Beaver) CPU: (4) x64 IntelĀ® Coreā¢ i3-6098P CPU @ 3.60GHz Memory: 1.73 GB / 15.57 GB Shell: 4.4.19 - /bin/bash Binaries: Node: 10.11.0 - /usr/bin/node npm: 6.7.0 - /usr/bin/npm npmPackages: react: 16.6.0-alpha.8af6728 => 16.6.0-alpha.8af6728 react-native: ^0.58.5 => 0.58.5 npmGlobalPackages: create-react-native-app: 2.0.2 react-native-cli: 2.0.1 react-native-rename: 2.4.0 react-native-slideshow: 1.0.1
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 21
- Comments: 64 (1 by maintainers)
For me, the issue was that although the app would come to the foreground on clicking on the app link (say from an SMS), the callback passed to
Linking.addEventListener
never got fired.So what I ended up doing is this: add an
AppState
listener to check the url fromLinking.getInitialURL
, and if it is a valid URL, redirect accordingly.Pls try this. componentDidMount() { Linking.addEventListener(āurlā, this.handleOpenURL); this.handleDeepLinkingRequests(); } handleDeepLinkingRequests = () => { Linking.getInitialURL() .then(url => { if (url) { this.handleOpenURL(url); } }) .catch(error => { // Error handling }); } };
handleOpenURL = (url) => { // your navigation logic goes here }
Notes: -> Linking.getInitialURL() method should only be called for the first time when the app is launched via app-swap -> For subsequent app-swap calls, handleOpenURL() method will be called as it is configured with linking event listener. -> remember to unsubscribe linking events in componentwillunmount()
@devanshu23598
try to add this code below in you
MainActivity.java
Is there an update on this issue ? Deep linking is an important feature, and this issue makes it pretty much unusable
@apamphilon try the below code. componentDidMount(){ this._checkInitialUrl() AppState.addEventListener(āchangeā, this._handleAppStateChange) Linking.getInitialURL().then(async (url) => { if (url) { console.log('Initial url is: ā + url); } }).catch(err => console.error(āAn error occurredā, err)); } componentWillUnmount() { AppState.removeEventListener(āchangeā, this._handleAppStateChange) }
this is working if the app is in background state too.
after investigation, I found the solution, add this code in your AppDelegate.m
reference: https://v5.rnfirebase.io/docs/v5.x.x/links/ios
So, apparently, it works just fine if you turn off the debugger
Same issue, seems like
Linking.getInitalURL()
works if the app is not yet launched, andLinking.addEventListener('url' callback)
works if the app is in foreground but neither seem to work for apps in background state.Found that while running with the debugger in iOS simulator it will work through the event listener but not with
Linking.getInitialURL()
.Also, my team found that without the debugger it works fine.
Doing a trace, it correctly sets the bridge values/info but when calling the method
getInitialURL
, the bridge no longer holds those values.It seems that there is a reset between both moments when the Debugger is present.
I hope this can be a hint to investigate the issue and for the solution. I will post more info if I find something more.
Not sure if others are having this problem, but for me the event listener doesnāt work (
Linking.addEventListener('url', link => ({ link }));
) Also, as has been mentioned, Linking.getInitialUrl only works on cold start, not from background. Edit: I donāt have the debugger runningFor those that are still facing the issue of not getting an event when a url is opened when the app is in background, I have a workaround for iOS.
in
openURL
in AppDelegate, add this line:[[NSUserDefaults standardUserDefaults] setObject:url.absoluteString forKey:@"deepLinkURL"];
In your component in JS, add this:
Make sure you add āRCTSettingsā as a sub-pod in your podfile.
I give you my hook that works grate on Android and IOS.
Also facing this issue. The event listener fails to fire if the app is not already open.
for me, the issue with using appState as a workaround is that on iOS Linking.addEventListener(āurlā) will get the latest url sent to the app - this is helpful if the app is used to share URLs. So each time a URL is sent to the app, it receives the correct one. Using appState and getInitialURL you only ever get the first url the app was launched with.
Is there any update on getting Linking.addEventListener(āurlā) working properly on Android?
I suggest you to follow the rn-firebase guide to do it right. I do that and my hook ends as follow:
This worked for me for both background and foreground ` import React, { useEffect, useCallback, useRef, Fragment } from āreactā; import { Linking, AppState } from āreact-nativeā;
const useDeepLink = (props) => { const appState = useRef(AppState.currentState), { callback } = props, handleDeepLink = useCallback( link => { if (link) { const url = typeof link === āstringā ? link : link.url; callback(url); } }, [], );
};
export default useDeepLink; `
Facing same issue 0.62.0
Facing the same issue. Not working for iOS. Cannot get the url (always null) when the app is closed when the link happens.
React Native Environment Info: System: OS: macOS 10.14.6 CPU: (8) x64 IntelĀ® Coreā¢ i7-6700HQ CPU @ 2.60GHz Memory: 353.30 MB / 16.00 GB Shell: 5.3 - /bin/zsh Binaries: Node: 11.9.0 - /usr/local/bin/node npm: 6.5.0 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 13.1, DriverKit 19.0, macOS 10.15, tvOS 13.0, watchOS 6.0 IDEs: Xcode: 11.1/11A1027 - /usr/bin/xcodebuild npmPackages: react: 16.8.3 => 16.8.3 react-native: ^0.59.9 => 0.59.9 npmGlobalPackages: react-native-cli: 2.0.1
=======>>>Method to catch Deep link when App opens <<<======= useEffect(() => { // Get the deep link used to open the app const getUrl = async () => { const universalLink = await Linking.getInitialURL();
},[]);
=======>>>Method to catch Deep link when App is In Background <<<=======
useEffect(() => {
}, []);
Facing the same issue on Android. The disabling debugger doesnāt help. The suggestion to access the URL with AppState & Linking.getInitialURL() doesnāt help either.
// Add Listener to catch a state
@RZulfikri Thank you for your response!! I added the code in MainActivity.java and it works fine when running through terminal. I want to open the app through web browser. That not work.
@DalbirKaur Thanks for the suggestion. I did try and do it this way but found that if the deep link has already been navigated to and then you switch screens and put the app back into the background and then relaunch, the event listener will fire again and navigate to that screen again.
Any thoughts?