React Native: AWS Amplify Auth.signOut() not working - react-native

React Native noob here, trying to implement AWS Amplify authentication flow into my project. But the Auth.signOut() function is not working at all. Nothing happens when I press the logout button.
const onLogOutPressed = async () => {
//Auth.signOut();
try {
await Auth.signOut({ global: true });
} catch (error) {
console.log('Error Logging Out', error);
}
}
My first version was purely Auth.signOut() as that was what the tutorial I was following did. Another guide suggested using the try method so I commented the first Auth function and added the rest.
Some help would be greatly appreciated. Do let me know if more info is required, thanks in advance.

If you're using React Native UI from Amplify and wrapped your component with withAuthenticator, below code should work.
class App extends React.Component {
constructor(props) {
super(props);
};
...
Auth.signOut().then(() => {
this.props.onStateChange(("signedOut");
});
}
// Functional component
const App = (props) => {
...
Auth.signOut().then(() => {
this.props.onStateChange("signedOut", null);
})
}
If you're not using React Native UI, then you need to handle redirection yourself. Auth.signOut() will only clear session.

Related

React Native component not making new query after mount

We're using react-native-web so native and web are in one code base. I have an instance where a user clicks the back button to return to a main page and this should fire a re-query of the backend. We're also using Apollo hooks for queries, useQuery
So far, this works for web but not for native. I tried creating a useEffect hook to check if navigation and specifically navigation.isFocused() like so:
const {
data,
loading: childProfilesLoading,
error: childProfilesError,
refetch: refetchChildProfiles,
} = useQuery(LIST_PROFILES, {
fetchPolicy: 'no-cache',
})
// this method also exists on the previous page
const goBack = () => {
if (history) {
history.goBack()
} else if (navigation) {
navigation.goBack()
}
}
useEffect(() => {
if (navigation?.isFocused()) {
refetchChildProfiles()
}
}, [navigation, refetchChildProfiles])
but this doesn't work. Is there something I'm missing in forcing a refetch on native?

how to perform deep linking on React Native Navigation

I have a request to implement deep linking in our React Native application whereby clicking a link will take them directly into the installed app. I am able to successfully direct them to the app. However, it must navigate to a certain page.
To address the problem, I use the code below. If there is a better approach to handle the problem, I would appreciate it if you could share it with me!
const useUrl = async () => {
const url = await Linking.getInitialURL();
if (url) {
Navigation.push(componentId, {
component: {
name: 'screen',
},
});
}
};
react-native and react-navigation both handle this as part of a feature set within the "Linking" that they offer. I can't find a way to handle that with React Native Navigation?
For me, I just add path to my stack navigator in react native like this
Product: {
screen: ProductScreen,
path: 'product/:productId'
},
and make sure your web that handle deep link have a similar path in routing. For example https://yourweb.com/product/:productId
And in your screen file, add this
useEffect(() => {
Linking.addEventListener('url', _handleDeepLink)
return () => {
Linking.removeEventListener('url', _handleDeepLink);
}
}
const _handleDeepLink = (event) => {
if (event) {
const route = event.url.replace(/.*?:\/\//g, '')
const id = route.match(/\/([^\/]+)\/?$/)[1];
if (id !== undefined) {
// do your code here if screen just opened via deep link
}
}
}

How to call api after screen is loaded react native

I am developing app using react native, and i have api call that retrieve json. How i can call another api in home screen immediately after it is loaded, this api i want to use for storing json data in order to use it in another screen, because i do not want the user to wait if he clicks.
The home.js that display the home screen is :
export class HomeScreen extends PureComponent {
constructor(props) {
super(props);
this.state = {
isLoading: true,
data: null,
isError: false,
}
}
componentDidMount() {
getArticles().then(data => {
this.setState({
isLoading: false,
data: data
})
}, error => {
Alert.alert("Error", "Something happend, please try again")
})
}
The function that gets articles:
export async function getArticles(){
try {
let articles = await fetch(``);
let result = await articles.json();
return result;
} catch (error) {
throw error
}
}
Can you recommend also tutorials or docs about cashing json response ?.
You can use any of these 3 third-party libraries to cache the response
[Redux] https://redux.js.org/introduction/getting-started
[React Native Async Storage] https://github.com/react-native-community/async-storage
[Context API] https://www.taniarascia.com/using-context-api-in-react/
You can call as many APIs in the componentDidMount. But if the second API is dependent on the first API then call second API in the then function

How to get the device token in react native

I am using react-native 0.49.3 version, My Question is how to get the device token in react native for both IOS and Android I tried with this link but it not working for me, right now I tried in IOS. how to resolve it can one tell me how to configure?
I tried different solutions and I've decided to use React Native Firebase.
Here you will find everything about Notifications.
Also, you can use the others libraries that come with Firebase, like Analytics and Crash Reporting
After set up the library you can do something like:
// utils/firebase.js
import RNFirebase from 'react-native-firebase';
const configurationOptions = {
debug: true,
promptOnMissingPlayServices: true
}
const firebase = RNFirebase.initializeApp(configurationOptions)
export default firebase
// App.js
import React, { Component } from 'react';
import { Platform, View, AsyncStorage } from 'react-native';
// I am using Device info
import DeviceInfo from 'react-native-device-info';
import firebase from './utils/firebase';
class App extends Component {
componentDidMount = () => {
var language = DeviceInfo.getDeviceLocale();
firebase.messaging().getToken().then((token) => {
this._onChangeToken(token, language)
});
firebase.messaging().onTokenRefresh((token) => {
this._onChangeToken(token, language)
});
}
_onChangeToken = (token, language) => {
var data = {
'device_token': token,
'device_type': Platform.OS,
'device_language': language
};
this._loadDeviceInfo(data).done();
}
_loadDeviceInfo = async (deviceData) => {
// load the data in 'local storage'.
// this value will be used by login and register components.
var value = JSON.stringify(deviceData);
try {
await AsyncStorage.setItem(config.DEVICE_STORAGE_KEY, value);
} catch (error) {
console.log(error);
}
};
render() {
...
}
}
Then you can call the server with the token and all the info that you need.

how to call a function on page refresh in react-redux?

Iam doing an app in react-redux and i want to hold my redux store on page refresh and thought to not make use of predefined libraries and hence i set the redux state to local state and making the api call in componentWillUnmount to restore redux state on page refresh.But i couldnt do that. Is their any approch to acheive this:
And my code is:
componentWillMount(){
this.setState({
activeUser:this.props.activeUser
})
}
componentWillUnmount(){
this.props.loginUser(this.state.activeUser.user);
}
activeUser is my redux state and this.props.loginUser() makes api call.And i tried of using event handlers as:
componentDidMount(){
window.addEventListener('onbeforeunload', this.saveStore)
}
componentWillUnmount(){
window.removeEventListener('beforeunload', this.saveStore)
}
saveStore(){
this.props.loginUser(this.state.activeUser.user);
}
but it didn't worked for me.
My understanding is that what you basically are trying to do is that, you want to persist your app state (user info, etc) between reloads.
One can use the localStorage API to achieve this effect.
I'll give one possible solution down here.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {activeUser: null};
}
componentWillMount() {
let activeUser = localStrorage.getItem("activeUser");
if (activeUser) {
this.props.receivedActiveUser(JSON.parse(activeUser));
}
}
componentWillReceiveProps(nextProps) {
this.setState({activeUser: nextProps.activeUser});
}
componentWillUnmount(){
if (this.state.activeUser) {
localStorage.setItem("activeUser", JSON.stringify(this.state.activeUser));
}
}
}
Ofcourse, you'll have to create a receivedActiveUser action which will update the store appropriately.