Login With React Native using Asyncronous storage - react-native

I am implementing login in React Native using Asynchronous storage. Here, when users login successfully, i keep the user object in the Asynchronous storage then i access this information to get the Authentication Key for my API request anytime I want to do a request.
When I login and information is stored in the Asynchronous storage, the current app session fails to get the just stored information hence all my authenticated request fails in this session. When I close the app and restart, I can successfully get the information from the Async storage stored in the previous session and make successful authenticated request.
I do not know what I am missing out in my code as I believe I need to refresh or reload the app internally after a successful login but I do not know how to do this in React Native. Any information or help is needed. Here is my Login code.
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem(USER_DATA, JSON.stringify(data)).then(val => {
console.log('just before reload in login')
Actions.menu(); //this solves the after login problem as it goes to the next page only after a successful AsyncStorage save
this.setState({ procesing: false });
})
.catch(err => {
this.setState({ procesing: false, error: "Couldn't log you in! Please try again" });
//console.log("\nCouldn't save to AsyncStorage: " + err + "\n");
});
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
After I have login, my request looks like ;
//for making a post request
post: (url,body) => {
return fetch(url+'?access-token='+this.state.user.auth_key, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
//'Autorization': 'Bearer token2'
},
})
but the user object is gotten from the Async storage as
getUser(){
return AsyncStorage.getItem("USER_DATA").then(value => {
if(JSON.parse(value) == null) {
return false;
} else {
return JSON.parse(value)
}
});
},
Any Information, Ideas, proposed solutions are highly welcome

If you are receiving the information correctly, you can pass the information to the next screen or use the asynchronous repository as it is now.
If use navigation
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
this.setState({ procesing: false });
this.navigation.navigate("LoginScreen",{data: JSON.stringify(data) })
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
this.state={
data : this.props.navigation.state.params.data
}
If use AsyncStorge
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem("USER_DATA", JSON.stringify(data));
this.setState({ procesing: false });
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
async componentDidMount() {
let data = await AsyncStorage.getItem("USER_DATA")
}

Related

Open screen on login - react native

I have a function that shows me an alert when the username and password are correct, but I want to send me a screen as soon as the username and password are correct, I have tried but I have not been able to do it.
in my attempts I have another validation which is if I log in but it does not validate, it is only verifying that the route exists but so put the password or the wrong email log in, I need it to validate and if the user and password are correct there yes let me log in.
const signIn = async({correo, password}: LoginData) => {
try {
await fetch('https://www.portal.multigobernanza.com/apiMultigobernanza/usuarios/login.php',
{
method:'POST',
headers:{
'Accept': 'application/json',
'content-Type': 'application/json'
},
body: JSON.stringify({"email":correo, "password" : password})
}).then(res => res.json())
.then(resData => {
Alert.alert(resData.message)
console.log(resData);
});
}catch (error) {
dispatch({type: 'addError',
payload: error.response.data.msg || 'Información incorrecta'})
}
};
other validation
const signIn = async({correo, password}: LoginData) => {
try {
const {data} = await cafeApi.post<LoginResponse>('/usuarios/login.php',{correo,password});
dispatch({
type: 'signUp',
payload: {
token: data.token,
user: data.usuario
}
});
await AsyncStorage.setItem('token', data.token);
} catch (error) {
dispatch({type: 'addError',
payload: error.response.data.msg || 'Información incorrecta'})
}
};
GIT
https://github.com/Giovannychvz/react-native
Take a look at how react-navigation suggest authentication flows. To achieve something like that, at the very least you will need a state variable that keeps track of when a user is signed in, and to modify your signIn function to update your state variable

facebook login working on development mode or server mod, when create a build, it's not working on any devices. react native app

feature unavailable facebook login in currently unavailable for this app, since we are updating additionl details for this app. please try again later
working only on my system and device, not working in others,
how to resolve this issue,please help
FacebookSignIn = async () => {
// Attempt login with permissions
try {
const result = await LoginManager.logInWithPermissions(['public_profile', 'email']);
console.log("fb login", result)
if (!result.isCancelled) {
await AccessToken.getCurrentAccessToken()
.then(async res => {
console.log("token", res);
// Create a Firebase credential with the AccessToken
const facebookCredential = auth.FacebookAuthProvider.credential(res.accessToken);
console.log("token", res);
// Sign-in the user with the credential
this.setState({ loder: true })
await auth().signInWithCredential(facebookCredential)
.then(response => {
console.log("Login Data", response);
const data = {
"name": response.additionalUserInfo.profile.first_name,
"email": response.additionalUserInfo.profile.email,
"user_type": 0
}
console.log(data);
fetchPostMethod('/facebook-sign-up', data)
.then(async response => {
this.setState({ loder: false })
if (response.status == 200) {
if (response.data.user_type == 0) {
try {
let user = JSON.stringify(response?.data?.user_type)
await AsyncStorage.setItem('SignINToken', response?.data?.token);
await AsyncStorage.setItem('UserType', user);
this.logmodl();
} catch (e) {
console.log("Login error", e)
}
} else {
this.user();
}
console.log("SignIn Successful", response);
} else {
this.field();
}
})
.catch(response => {
this.setState({ loder: false })
console.log("SignIn faild", response.message);
})
this.setState({ FacebookUserInfo: response });
})
.catch(error => {
console.log('Login Data Error', error);
})
})
.catch(error => {
console.log('Something went wrong obtaining access token ', error);
})
}
} catch (error) {
console.log("ERROR WHILE LOGIN! ", error);
}
}
feature unavailable facebook login in currently unavailable for this app, since we are updating additionl details for this app. please try again later
working only on my system and device, not working in others,
how to resolve this issue,please help
Pay attention! For enable Facebook login for other users you need visit the Facebook developer site
and enable work mode for application, moving this switch

react-native facebook logout

I'm struggling to setup a logout action in my app, considering the User has logged in through Facebook provider (react-native-fbsdk). What is the proper way to setup a logout? So, when Users get back to my App and try to login, email and password should be requested again. pls help
To login I'm using:
LoginManager.logInWithReadPermissions(['public_profile', 'email']);
I have tried to call LoginManager.logOut(), LoginManager.setLoginBehavior('I have tried all types'), but did not revoke permissions.
I've also tried to call GraphRequest as per code below but I didn't get the desired result.
logoutFacebook = () => {
AccessToken.getCurrentAccessToken()
.then(data => {
return data.accessToken.toString();
})
.then(accessToken => {
const logout = new GraphRequest(
'me/permissions/',
{
accessToken,
httpMethod: 'DELETE'
},
(error, result) => {
if (error) {
console.log(`'Error fetching data: '${error.toString()}`);
} else {
console.log(result);
LoginManager.logOut();
}
}
);
new GraphRequestManager().addRequest(logout).start();
})
.catch(error => {
console.log(error);
});
}

How to store facebook token in AsyncStorage React Native(Expo)

I am using Expo to Login User with Facebook, I am receiving token with Graph Api but when I try to add the token in Async Storage it is not working.
Please see the code below:
async logIn() {
try {
const {
type,
token,
} = await Facebook.logInWithReadPermissionsAsync('<APP_ID>', {
permissions: ['public_profile'],
});
if (type === 'success') {
// Get the user's name using Facebook's Graph API
fetch(`https://graph.facebook.com/me?access_token=${token}`)
.then((res) => res.json())
.then((tokenKey) => AsyncStorage.setItem('userToken',tokenKey))
.then(() => this.props.navigation.navigate('App'))
} else {
// type === 'cancel'
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
I am receiving the token when I console it
fetch(`https://graph.facebook.com/me?access_token=${token}`)
.then((res) => res.json())
.then((tokenKey) => console.log('userToken',tokenKey))
.then(() => this.props.navigation.navigate('App'))
Please help, I am new to react native and asynchronous programming in JavaScript. TIA :)
Try this if you want to get item from AsyncStorage
AsyncStorage.getItem('userToken', (error, result) => {
if (result) {
//result
}
else {
//error
}
});
Are you getting token from AsyncStorage with getItem?
AsyncStorage.getItem('userToken').then((token) => {
this.setState({hasToken: token !== null,localToken : token})
});
Sorry folks the problem was from my side, I was trying to store an object directly into Async Storage, whereas Async Storage only accepts values in String format. I used
.then((tokenKey) => AsyncStorage.setItem('userToken',JSON.stringify(tokenKey)))
and it fixed the problem,Thanks all for your help

react-native - check expiration of jwt with redux-thunk middleware before every call to API

For my react-native app I need to make sure that before every fetch request to server the use-case below should be executed
-> check the expire date of token that is saved to redux.
--> If token is not expired, app keeps going on with requested fetch to server
--> If token expired, app immediately makes new request to refresh token without making user knows it. After successfully refreshing token, app keeps going on with requested fetch to server
I tried to implement middleware with redux-thunk, but I do not know whether it's good design or not. I just need someone experienced with redux and react to give me feedback over my middleware code.
This is how I make requests to server oveer my app's component through dispatching the checkTokenAndFetch - action creater.
url = "https://———————";
requestOptions = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + this.props.token
}
};
dispatch(authActions.checkTokenAndFetch(url, requestOptions))
.then((data) => {
})
here is action creator - checkTokenAndFetch located in authActions.js
file where my actions located
function checkTokenAndFetch(url, requestOptions){
return dispatch => {
if(authServices.isTokenExpired()){
console.log("TOKEN EXPIRED");
authServices.refreshToken()
.then(
refreshToken => {
var arr = refreshToken.split('.');
decodedToken = base64.decode(arr[1]);
newTokenExpDate = JSON.parse(decodedToken).exp;
dispatch(writeTokenToRedux(refreshToken,newTokenExpDate));
},
error => {
Alert.alert("TOKEN refresh failed","Login Again");
Actions.login();
}
);
}
else{
console.log("TOKEN IS FRESH");
}
return authServices.fetchForUFS(url, requestOptions)
.then(
response => {
return response;
},
error => {
}
)
;
}
}
Here is isTokenExpired and refreshToken functions that I call for case of token expire, located in another file named authServices.js.
function isTokenExpired(){
var newState = store.getState();
var milliseconds = (new Date).getTime();
var exDate = newState.tokenExpDate;
return milliseconds>exDate*1000
}
function refreshToken(){
var refreshToken = store.getState();
return fetch('https://—————————', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer ' + refreshToken.token
}
})
.then((response) => {
return response._bodyText;
})
.catch((error) => {
return error;
})
}
and my fetchForUFS function in authServices.js to make a call to server after completeing token-check(refresh) stuff.
function fetchForUFS(url,requestOptions){
return fetch(url, requestOptions)
.then((response) => {
return response.json();
})
.then((responseData) =>{
return responseData;
})
.catch((error) => {
})
}
I've read tons of redux-thunk, redux-promise and middleware documentation and I'm yet not sure whether I am implementing middleware logic truly?