Linking event handler not fired when app is in background - android

I am implementing logging in using Facebook, Twitter, etc.. When the user clicks on the icon, safari opens, the user logs in, and then the webpage redirects to appname://login.
I followed this article https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e, and my code looks like the following:
componentDidMount(){
Linking.getInitialURL()
.then((url) => {
if (url) {
// Alert.alert('GET INIT URL','initial url ' + url)
this.resetStackToProperRoute(url)
}
})
.catch((e) => {})
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL = (event) => {
console.log('event: ' + event);
}
The problem is nothing gets printed on the console. I think the problem is that the handler is not fired when the app comes from the background. Is there a way around it?
thanks

Related

Why is notification navigation routing not working when app is in background using FCM in Ionic Angular app

I have installed FCM notification plugin and added following code in
FCM.onNotification().subscribe(data => {
if (data.wasTapped) {
this.route.navigateByUrl(`${data.routeUrl}`);
console.log("Received in background");
} else {
this.localNotifications.schedule({
title: data.title,
text: data.body,
foreground: true
})
this.localNotifications.on("click").subscribe((notification: any) => {
this.navCtrl.navigateForward([data.routeUrl]).then((entry) => {
}).catch((err) => {
console.log('Error while navCtrl:- ' + JSON.stringify(err));
});
})
console.log("Received in foreground");
};
});
With this I am able to navigate to a screen from the path provided in the body of notification when app is open but when app is in closed state or in background I'm unable to navigate to that screen
Please help me out regarding this issue
Regards

When React native RNIap.purchaseErrorListener is called?

I have integrated react-native-iap for in app purchase.
Android Payment flow works properly(payment success, payment failed and user cancel payment).
But facing issue when purchase card is shown and I click outside the card, card is dismissed but not getting event inside RNIap.purchaseErrorListener .
Hence my state variable did not updated.
here is sample:
Listener code :
useEffect(() => {
initPurchase()
purchaseErrorSubscription = RNIap.purchaseErrorListener(
(error) => {
console.log('purchaseErrorListener INAPP>>>>', error);
if(error.code == "E_USER_CANCELLED") {
//for cancelled or refund sku
setSelectedPackage(null)
RNToasty.Show({
title: error.message,
});
} else if(error.code == "E_ITEM_UNAVAILABLE") {
//item not found
setSelectedPackage(null)
} else {
setSelectedPackage(null)
}
},
);
}, [])
Listener not called when I perform above action.
Can anyone help me to get this event?
Thanks in advance!!
you need to put this in a function, and in useEffect call this function
const checkCurrentPurchaseError = async () => {
purchaseErrorListener(async currentPurchaseError => {
if (currentPurchaseError) {
Here is your code...
}
});
};
useEffect(() => {
checkCurrentPurchaseError(currentPurchaseError);
}, []);

Linking.getInitialURL() is not being cleared after used for deeplink

I've had this problem for like 2 weeks. I used Wix's Navigation for navigating around the app. I followed this tutorial for implementing the deeplink/universal link.
I have a base class called BaseScreen where I keep all the deeplink handler like in the tutorial. This BaseScreen would looks like this:
componentDidMount(){
// this handles the case where the app is closed and is launched via Universal Linking.
Linking.getInitialURL()
.then((url) => {
if (url) {
// Alert.alert('GET INIT URL','initial url ' + url)
this.resetStackToProperRoute(url)
}
})
.catch((e) => {})
// This listener handles the case where the app is woken up from the Universal or Deep Linking
Linking.addEventListener('url', this.appWokeUp);
}
componentWillUnmount(){
// Remove the listener
Linking.removeEventListener('url', this.appWokeUp);
}
appWokeUp = (event) => {
// this handles the use case where the app is running in the background and is activated by the listener...
// Alert.alert('Linking Listener','url ' + event.url)
this.resetStackToProperRoute(event.url)
}
resetStackToProperRoute = (url) => {
// grab the trailing portion of the url so we can use that data to fetch proper information from the server
let trailing = url.slice(url.lastIndexOf('=') + 1, url.length)
// go to the desired screen with the trailing token grabbed from the url
this.props.navigator.resetTo({
screen: 'NewPassword',
overrideBackPress: true,
passProps: {
token: trailing
},
animated: true,
animationType: 'fade',
navigatorStyle: {
navBarHidden: true,
}
})
}
When the app launch, it'll show the screen LoginScreen which extends the BaseScreen above. After killing the app, click the url from the mail, the app launches LoginScreen first, then it'll redirect to the screen NewPassword, and after everything has done, I'll redirect back to LoginScreen by:
this.props.navigator.resetTo({
screen: 'LoginScreen',
animated: true,
overrideBackPress: true,
animationType: 'fade',
navigatorStyle: {
navBarHidden: true,
}
})
But the Linking.getInitialURL() of the LoginScreen still receive the old url, so it'll redirect to NewPassword again, and it's a loop.
I've also tried to pass: passProps: {} option when resetTo the LoginScreen but no luck.
I guess the only way to fix it is to clear the initialUrl manually after everything's done in NewPassword screen. The listener for the BaseScreen should be there because if I don't kill the app (just minimize it), the listener should be running to navigate to NewPassword.
Wix's navigation has a doc for Deeplink, I tried putting method onNavigatorEvent(event) into the BaseScreen but it doesn't get called. I don't know if I miss something.
Thank you for your time. Any idea would be appreciated
Linking.getInitialURL() gives us the same Url when we come back to the same page again, to Overcome this we can do a simple condition of not to call the DeepLink function. Something like...
Step 1: First init a dummyDeepLinkedUrl String .
var dummyDeepLinkedUrl;
Step 2: Check for the condition like, if deeplinkUrl is coming from Linking.getInitialURL() and deeplinkUrl is not equal to the dummyDeepLinkedUrl .
if (url && url != dummyDeepLinkedUrl) {}
Step 3: If not same call the Deeplink Function and assign the deeplinkUrl to dummyDeepLinkedUrl.
this.navigateToRespectivePage(url);
dummyDeepLinkedUrl = url;
Finally this will look like :
Linking.getInitialURL().then(url => {
if (url && url != dummyDeepLinkedUrl) {
this.navigateToRespectivePage(url);
dummyDeepLinkedUrl = url;
}
});
There are two ways to handle URLs that open your app.
If the app is already open, the app is foregrounded and a Linking event is fired You can handle these events with
Linking.addEventListener(url, callback).
If the app is not already open, it is opened and the url is passed in as the initialURL You can handle these events with
Linking.getInitialURL(url) -- it returns a Promise that resolves to
the url, if there is one.
You can read more detail
Here is the example
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
initialised: false
}
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
Linking.addEventListener('url', event => {
console.log('deep link from background', event.url)
})
}
_handleAppStateChange = async (nextAppState) => {
const url = await Linking.getInitialURL();
if (url !== null && !this.state.initialised) {
this.setState({ initialised: true })
console.log('deep link from init app', url)
}
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
Linking.removeEventListener('url')
}
}

firebase dynamic link with react-navigation

I have followed this document https://rnfirebase.io/docs/v4.1.x/links/android and able to run adb shell am start -W -a android.intent.action.VIEW -d "https://abc123.app.goo.gl" com.myapp.superapp to start the app.
How can open a dynamic link https://abc123.app.goo.gl it open the VideoScreen and pass the contentparam
Video:{
screen : VideoScreen,
path:'wvc/:contentparam',
}
So I tried this when clicking https://abc123.app.goo.gl (dynamic link):
componentDidMount () {
Linking.getInitialURL().then((url) => {
console.log('Initial url is: ' + url);
}).catch(err => console.error('An error occurred', err));
}
However app opened but console.log given null
For some reason firebase.links().onLink((url) does not work in RNFB v6.
Here is a comment on this bug from one of RNFB maintainers
https://github.com/invertase/react-native-firebase/issues/3008
Use should use react native Link instead, as a temporary workaround:
https://facebook.github.io/react-native/docs/0.47/linking
Here is an example you can use:
useEffect(() => {
Linking.getInitialURL()
.then(url => {
if (url) {
console.log('Initial url is: ' + group);
}
})
.catch(err => console.error('An error occurred', err));
}, []);
You have to listen to firebase links
componentDidMount() {
const unsubscribe = firebase.links().onLink((url) => {
console.log('dynamic links', url)
// do navigate with url above
// you have to handle your self
});
}
componentWillUnmount() {
unsubscribe()
}
docs: https://rnfirebase.io/docs/v5.x.x/links/reference/links#onLink

Automatic logging in - Nodejs and Android system

I am working on Registration and Login system in Nodejs and Android based on this tutorial:
https://www.learn2crack.com/2016/09/android-user-registration-login-node-server.html
https://www.learn2crack.com/2016/09/android-user-registration-login-node-client.html
It works fine, however I want to create a system in which user stays logged in- automatic login everytime he turns on the app. At the moment the logging in is based on token created with 'jsonwebtoken' and it works only if user gives email and password:
router.post('/authenticate', (req, res) => {
const credentials = auth(req);
if (!credentials) {
res.status(400).json({ message: 'Invalid Request !' });
} else {
login.loginUser(credentials.name, credentials.pass)
.then(result => {
const token = jwt.sign(result, config.secret, { expiresIn: 1440 });
res.status(result.status).json({ message: result.message, token: token });
})
.catch(err => res.status(err.status).json({ message: err.message }));
}
});
I couldn't find anything specific how to solve it. Could anyone tell me what is the best way to do it and support me with a link or tutorial?

Categories

Resources