React Native Share Method Multiple Windows - react-native

I’m using react native share, to share text content. The issue is multiple windows are opened over each other on clicking share button multiple times. Even I have disabled button on share click but it is of no use as well.
The standard way is if share window is already open, on clicking the share button again the window get closed. How can it be done?
<Button
transparent
disabled={this.state.isShareDisabled}
onPress={() => this.onShare()}>
onShare() {
if(!this.state.isShareDisabled)
{
this.setState(
{
isShareDisabled:true
}
)
Share.share({
message: “Message test”,
url: ”www.google.com”,
title: “Title test”
}, {
// Android only:
dialogTitle: 'Share',
// iOS only:
excludedActivityTypes: [
'com.apple.UIKit.activity.PostToTwitter'
]
}) .then((result) => {
this.setState(
{
isShareDisabled: false,
}
)
})
}
}

Use dismissed action. Share event support it on both android and iOS.

I resolved it by doing the following, just required to check dismissedAction.
onShare() {
if(!this.state.isShareDisabled)
{
this.setState(
{
isShareDisabled:true
}
)
Share.share({ message: 'test',
url: 'test url',
title: 'test title'
},
{
// Android only:
dialogTitle: 'Share',
// iOS only:
excludedActivityTypes: [
'com.apple.UIKit.activity.PostToTwitter'
]
}).then(({action, activityType}) => {
if(action === Share.dismissedAction) {
this.setState(
{
isShareDisabled: false,
}
)
}
else {
this.setState(
{
isShareDisabled: false,
}
)
}
});
}
}

Related

Is it possible to integrate the FaceId and TouchID in React-Native project?

I'm trying to implement local authentication in my react-native mobile application. I'm using react-native-touch-id, But the faceId module is not working, it always asks for the fingerprint only. I did a lot of googling but was unable to find a satisfactory answer. It would be very helpful if anyone of you can help me with this.
//this is for checking support of face id and touch id on your device
TouchID.isSupported(this.optionalConfigObject)
.then((biometryType) => {
if (biometryType === "FaceID") {
console.log("FaceID is supported.");
} else {
console.log("TouchID is supported.");
TouchID.authenticate("", this.optionalConfigObject)
.then((success) => {
Alert.alert("Authenticated Successfully");
console.log("Success", success);
})
.catch((err) => {
console.log("Cancel Pressed");
BackHandler.exitApp();
});
}
})
// Failure code if the user's device does not have touchID or faceID enabled
.catch((err) => {
Alert.alert("", "Please add fingerprint from your device and try again", [
{
text: "OK",
onPress: () => {
console.log("OK Pressed"), BackHandler.exitApp();
},
},
]);
console.log("error in catch=> " + err);
});

Setting up react native push notification with wix react native navigation v3 - problem when app is closed

I am sending a notification that navigates the user to a specific screen when the notification is clicked.
This works perfectly when the app is opened or running in the background, however, when the app is closed onNotification is not being called.
I am using react native push notification and wix react native navigation V3.
I notice the problem by putting a console log inside on notification and it was never called.
In index.js I have the follwing code
import { start } from './App';
start();
In App.js
import React from 'react';
import { Navigation } from 'react-native-navigation';
import { Provider } from 'react-redux';
import configureStore from './src/configureStore';
import { configurePush } from './src/utils/push-notifications';
import Login from './src/components/views/Login';
import Home from './src/components/views/Home';
import Cart from './src/components/views/Cart';
import CartDetail from './src/components/views/Cart/Detail';
import Orders from './src/components/views/Orders';
... the rest of the screens
const store = configureStore();
configurePush(store);
export function registerScreens() {
Navigation.registerComponent('provi.Login', () => (props) => (
<Provider store={store}>
<Login {...props} />
</Provider>
), () => Login);
Navigation.registerComponent('provi.Home', () => (props) => (
<Provider store={store}>
<Home {...props} />
</Provider>
), () => Home);
Navigation.registerComponent('provi.Cart', () => (props) => (
<Provider store={store}>
<Cart {...props} />
</Provider>
), () => Cart);
... the rest of the screens
}
export function start() {
registerScreens();
Navigation.events().registerAppLaunchedListener(async () => {
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: 'provi.Login',
options: {
animations: {
setStackRoot: {
enabled: true
}
},
topBar: {
visible: false,
drawBehind: true,
background: {
color: '#30DD70'
},
},
bottomTabs: {
visible: false
}
}
}
}],
}
}
});
});
}
Then the configuration of the notification is the following:
import PushNotificationIOS from "#react-native-community/push-notification-ios";
import { Navigation } from 'react-native-navigation';
import PushNotification from 'react-native-push-notification';
import DeviceInfo from 'react-native-device-info';
import fetchApi from "../store/api";
import { addNotification } from '../store/notifications/actions';
import { SENDER_ID } from '../constants';
export const configurePush = (store) => {
PushNotification.configure({
onRegister: function(token) {
if (token) {
const registerData = {
token: token.token,
uid: DeviceInfo.getUniqueID(),
platform: token.os
}
// console.log(registerData);
fetchApi('/notificaciones/register', 'POST', registerData).catch(err => console.log(err))
}
},
onNotification: function(notification) {
if (notification) {
store.dispatch(addNotification(notification)); // Almacena la notification
const action = notification.data.click_action;
if (action === 'oferta') {
const remotePost = notification.data.data;
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: 'provi.Home',
options: {
animations: {
setStackRoot: {
enabled: true
}
},
topBar: {
visible: true,
drawBehind: false,
},
passProps: {
test: 'test',
notification: remotePost
}
}
}
}],
}
}
});
} else if (action === 'seller') {
const remoteSeller = notification.data.data;
Navigation.push('Home', {
component: {
name: 'provi.Seller',
passProps: {
id: remoteSeller._id,
featureImage: remoteSeller.featureImage
},
options: {
topBar: {
title: {
text: 'Nueva Marca!'
}
},
bottomTabs: {
visible: false,
drawBehind: true
}
}
}
});
} else if (action === 'sellerClosingSoon') {
const remoteSeller = notification.data.data;
Navigation.push('Home', {
component: {
name: 'provi.ClosingSoon',
passProps: {
id: remoteSeller._id,
featureImage: remoteSeller.featureImage
},
options: {
topBar: {
title: {
text: 'Marcas que cierran pronto'
}
},
bottomTabs: {
visible: false,
drawBehind: true
}
}
}
});
}
}
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
senderID: SENDER_ID,
popInitialNotification: true,
requestPermissions: true
});
}
I am expecting to see the console.log at least but it's not happening.
What is the correct setup for RNN V3 with RN push notification?
the notifications are two types: background and foreground.
You use foreground notifications. But when an app is closed and you receive a new notification your callback cannot be fired.
You should use something like getInitialNotification to get the notification data.
https://github.com/zo0r/react-native-push-notification/blob/master/component/index.android.js#L19
I hope that helps.
Thanks

How to Navigate to Screen after GPS been enabled?

When the User is enabled the GPS I want to navigate it to AuthScreen.js. I'm using react-native-navigation v1 but there is no feature that can navigate just to simple screen, only push and modal but I don't want to use it.
Also using this: react-native-android-location-services-dialog-box
Here are my codes:
componentDidMount() {
this.gpsLocation();
}
gpsLocation = () => {
if (Platform.OS === 'android') {
LocationServicesDialogBox.checkLocationServicesIsEnabled({
message: "<h2>Use Location?</h2> \
This app wants to change your device settings:<br/><br/>\
Use GPS for location<br/><br/>",
ok: "Yes",
cancel: "No",
style: {
backgroundColor: '#4f6d7a',
positiveButtonTextColor: '#000000',
negativeButtonTextColor: '#000000'
},
enableHighAccuracy: true,
showDialog: true,
openLocationServices: true,
preventOutSideTouch: true,
preventBackClick: true,
providerListener: true
}).then(function(success) {
console.log(success)
// return <AuthScreen/>
}).catch((error) => {
console.log(error.message);
});
};
DeviceEventEmitter.addListener('locationProviderStatusChange', function(status) {
console.log(status);
});
};
componentWillUnmount() {
LocationServicesDialogBox.stopListener();
};
render() {
if(!this.state.nextScreen) {
return (
<View style={styles.container}>
</View>
);
} else {
return <AuthScreen/>
}
};
If you really don't want to navigate, you can use the .then() callback in which you're already logging the success parameter. According to the doc, success is an object with the following structure:
{
alreadyEnabled: false,
enabled: true,
status: "enabled"
}
You just need to check if success.enabled is true and if that's the case call setState({ nextScreen : true });
Edit: Here's the code, as requested:
// MyView.js
componentDidMount()
{
this.checkOrRequestLocationPermission();
}
checkOrRequestLocationPermission()
{
if (Platform.OS === 'android')
{
LocationServicesDialogBox.checkLocationServicesIsEnabled({
// Your config
// ...
})
.then(result => {
if (result.enabled)
{
this.setState({
nextScreen : true
});
}
// The above could be replaced by this
// this.setState({
// nextScreen : result.enabled
// });
})
.catch(error => {
console.warn('Error requesting location permission ' + error);
});
}
}
render() {
if(!this.state.nextScreen) {
return (
<View style={styles.container} />
);
}
else {
return <AuthScreen/>
}
};

Using OneSignal.registerForPushNotifications, then approve not registering

I am user OneSignal in combination with React-Native to setup the push notifications. In my app, users need to be logged in, in order receive push notifications (or to give permission).
The issue that I am having, is that when the user logs in, they get my custom popup, asking if they would like to receive messages. If they click yes, they iOS popup shows, asking for permission.
When I click yes again, and check the OneSignal users dashboard, to see which users have registered for the push notifications. I see mine, but as opted out, which is not correct.
So I am wondering if there is a bug in the code of OneSignal (already in contact with them, but is going slow) or my code is wrong.
I am using;
React-native 0.56
react-native-onesignal: 3.2.7
The following code is what I currently have:
componentWillMount() {
OneSignal.init("{key}", {kOSSettingsKeyAutoPrompt : false});
AsyncStorage.multiGet(['firstTime', 'subscribed']).then((response) => {
this.setState({
firstTime: JSON.parse(response[0][1]) != null ? JSON.parse(response[0][1]) : true,
subscribed: JSON.parse(response[1][1]) != null ? JSON.parse(response[1][1]) : false
});
setTimeout(() => {
if (Platform.OS === 'android' && !this.state.subscribed && this.state.firstTime) {
OneSignal.setSubscription(false);
}
}, 200);
});
OneSignal.addEventListener('received', this.onReceived);
OneSignal.addEventListener('opened', this.onOpened);
OneSignal.addEventListener('ids', this.onIds);
}
componentDidMount () {
NetInfo.isConnected.addEventListener('connectionChange', this.handleConnectivityChange);
AsyncStorage.getItem('firstTime').then((result) => {
!this.isCancelled && this.setState({
firstTime: JSON.parse(result) != null ? JSON.parse(result) : true
})
});
firebase.auth().onAuthStateChanged((user) => {
if (user) {
setTimeout(() => {
if (!this.state.subscribed && this.state.firstTime) {
Alert.alert(
I18n.t('notifications title'),
I18n.t('notifications subtitle'),
[
{text: I18n.t('notifications no'), onPress: () => {
setTimeout(() => {
AsyncStorage.multiSet([['firstTime', JSON.stringify(false)], ['subscribed', JSON.stringify(false)]]);
}, 100)
}, style: 'cancel'},
{text: I18n.t('notifications ok'), onPress: () => {
if (Platform.OS === 'android') {
OneSignal.setSubscription(true);
}else if (Platform.OS === 'ios') {
// OneSignal.setLogLevel(6, 0);
OneSignal.registerForPushNotifications();
}
setTimeout(() => {
AsyncStorage.multiSet([['firstTime', JSON.stringify(false)], ['subscribed', JSON.stringify(true)]]);
}, 100)
}}
],
{ cancelable: false }
)
}
}, 500)
}else{
OneSignal.setSubscription(false);
}
SplashScreen.hide();
});
};
Hope you guys can help out.
Cheers,
Ah, I found the cause of the issue. The second setSubscription(false) in the else statement was unsubscribing even-though I didn't.
So removing the else is fixing it for me.

wix react native navigation v2 | unable to disable open gestures

In the RNN v1 we can use disableOpenGesture: true, but in v2 it doesn't work anymore. I tried the next but without success:
sideMenu: {
right: {
component: {
id: 'sideDrawer',
name: DRAWER,
options: {
disableOpenGesture: true,
}
}
},
center: {...}
}
I found a temporal solution that fits my use case (I have a hamburger button which toggle the drawer):
export const openDrawer = () => {
Navigation.mergeOptions('sideDrawer', {
sideMenu: {
right: {
enabled: true,
visible: true
}
}
})
}
export const closeDrawer = () => {
Navigation.mergeOptions('sideDrawer', {
sideMenu: {
right: {
visible: false,
enabled: false,
}
}
})
}
Basically I disable the drawer completely when it's not shown. When disabled obviously gestures are disabled as well. Again this fits my use case and might not suite anyone.
Edit: it turned out my solution works on iOS only but also has this issue:
https://github.com/wix/react-native-navigation/issues/3837.
On Android it doesn't work at all.
I'm using "react-native": "0.56.0" and "react-native-navigation": "2.0.2485".