Restarting expo app on logout without ejecting - authentication

I would like to reload the entire expo application when I click on the logout function and I want to do it without ejecting the application, is there a workaround for this? Any help would be appreciated. I have researched on the react-native-restart library but it requires me to eject my application.
These are my current codes
logOut() {
Auth.currentAuthenticatedUser({
bypassCache: false
}).
then(
user => user.signOut()
)
.catch(err => console.log(err))
}

You can use
import { Updates } from 'expo';
Updates.reload()
It's generally used to reload apps when new update is available, but should also work in your case

After expo remove
Updates.reload()
then you can use
await Updates.reloadAsync()
to reload application instead.

Related

React-Native Expo Managed App: How do I enable sharing?

I'm using Expo SDK v. 45, iPhone 13 Pro (iOS v. 15.5), expo-sharing v. 10.1.1.
I'm currently using expo start --dev-client to test my app on my iPhone. I need to be able to share a file, created inside the app, with the outside world. I found expo-sharing to achieve this. Unfortunately, when I run
install * as Sharing from 'expo-sharing';
...
useEffect( async () => {
const canShare = await Sharing.isAvailableAsync();
if (canShare) {
console.log("available");
} else {
console.log("Not available");
}
}, []);
I get 'Not available'.
What must I do to get my app to allow sharing? I can't find anything in the Expo documentation.
Thank you.
In case anybody else has a similar issue: all I had to do was rebuild the app and reinstall it on my phone. Now it works.

AsyncStorage.removeItem(key) not removing items unless App restarted or after several minutes

I have a logout Button that binds to the following method.
async onLogoutButtonPress() {
await AsyncStorage.removeItem('accessToken');
await AsyncStorage.removeItem('mobileNumber');
await AsyncStorage.removeItem("businessId");
await AsyncStorage.clear();
this.props.navigation.navigate('Login');
}
I understand that AsyncStorage.removeItem is an asynchronous operation and it returns a Promise. However notice that I am using await that waits for Promise to resolve before navigating to Login.
I also tried the alternate then syntax
AsyncStorage.removeItem(('accessToken')).then(() => {console.log('resolved') },
() => { console.log('rejected') })
And all of them show as resolved in the console, but some how the items persist unless I close and restart the app. I am seeing this behavior on Android.
Why aren't the items getting removed until I restart the app ?
I am using expo for the build, if that matters.
I am using
import { AsyncStorage} from 'react-native';
Here's the react-native version.
"react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",

Clear browser cookies React Native 0.60

My app is using Instagram's REST API, in order for a user to logout and login with a different account I have to clear the cookies for www.instagram.com from the browser. I have been using react-native-cookie with RN 0.59.10 and it has been working fine.
After upgrading to RN 0.60 I can't use the react-native-cookie or any of its alternate packages because they don't support auto-linking. The solution I have found is using the RCTNetworking module from the react-native library. You can see the solution here.
Code
var RCTNetworking = require('RCTNetworking');
export const logout = () => {
return new Promise((resolve, reject) => {
RCTNetworking.clearCookies(result => {
if (!result) {
console.log('Error Message');
reject()
}
store.dispatch({ type: "RESET_APP_STATE" });
NavigationService.navigate("AuthLoading");
resolve()
});
});
};
The code runs fine. The app's state is cleared and the user is navigated to the login screen, but when I open the Instagram page in the webView instead of asking for the username and password, it directly logs me in.
You should use the community-version of react-native-cookies which can be found here: https://github.com/react-native-community/react-native-cookies
I am happily using this in combination with version 0.61.5 of React-Native.

How to detect screenshots with React Native (both Android and iOS)

I am trying to detect if a user takes a screenshot while using a smartphone app that I have built. I am building my project with React Native.
I have been told that I can possibly prevent screenshots for Android but not for iOS. but can I still detect whether a user attempts to take a screenshot so that I can at least send a warning via Alert?
Thanks in advance
I tried react-native-screenshot-detector but it did not work
you can use this package it supports android&ios screenshot detecting react-native-detector
import {
addScreenshotListener,
removeScreenshotListener,
} from 'react-native-detector';
// ...
React.useEffect(() => {
const userDidScreenshot = () => {
console.log('User took screenshot');
};
const listener = addScreenshotListener(userDidScreenshot);
return () => {
removeScreenshotListener(listener);
};
}, []);
There is no package for it currently.

How to force users to update the app using react native

I have updated my app on app and play store and I want to force my app users to update the new version of app in App store and playstore.
You can check for the App Store / Play Store version of your app by using this library
react-native-appstore-version-checker.
In expo app you can get the current bundle version using Constants.nativeAppVersion. docs.
Now in your root react native component, you can add an event listener to detect app state change. Every time the app transitions from background to foreground, you can run your logic to determine the current version and the latest version and prompt the user to update the app.
import { AppState } from 'react-native';
class Root extends Component {
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextState) => {
if (nextState === 'active') {
/**
Add code to check for the remote app version.
Compare it with the local version. If they differ, i.e.,
(remote version) !== (local version), then you can show a screen,
with some UI asking for the user to update. (You can probably show
a button, which on press takes the user directly to the store)
*/
}
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
}
import VersionCheck from 'react-native-version-check';
i have used version check lib for this purpose and approach i used is below. if version is lower i'm opening a modal on which an update button appears, and that button redirects to app store/google play
componentDidMount() {
this.checkAppUpdate();
}
checkAppUpdate() {
VersionCheck.needUpdate().then(res => {
if (res.isNeeded) {
setTimeout(() => {
this.setState({openModal: true});
});
}
});
}
updateApp = () => {
VersionCheck.getStoreUrl({
appID: 'com.showassist.showassist',
appName,
})
.then(url => {
Linking.canOpenURL(url)
.then(supported => {
if (!supported) {
} else {
return Linking.openURL(url);
}
})
.catch(err => console.error('An error occurred', err));
})
.catch(err => {
console.log(`error is: ${err}`);
});
};
For future readers.
If you are using Expo managed workflow, install this package react-native-version-check-expo using yarn add react-native-version-check-expo or npm install react-native-version-check-expo.
Consult the package documentation on Github for usage guidelines.
I'm using react-native-version-check-expo library to achieve this. Working fine for me.
if you are looking for an easy to integrate built in solution. You can use App Upgrade https://appupgrade.dev/ service to force update your mobile apps.
Create new version entry for your app version that you want to update in the app upgrade service and select whether you want to force it or just want to let users know that new version is available.
Integrate your app with App Upgrade using available SDK. Official SDK are available for React Native, Flutter, Expo, Android and iOS(Swift).
The SDK will take care of the rest.
Whenever you want to force upgrade a version just create a version entry in app upgrade dashboard.
You can also integrate using API. Just call the appupgrade api from your app with the required details such as your app version, platform, environment and app name.
The API will return you the details.. that this app needs to be updated or not.
Based on the response you can show popup in your app.You can call this API when app starts or periodically to check for the update. You can even provide a custom message.
API response:
See the response has force update true. So handle in the app by showing popup.
You can find the complete user documentation here. https://appupgrade.dev/docs
Thanks.