What my app should do is it uses google oauth for login and the server will then return a create a user (if user has not been created) and log the user in (by creating session).
I am certain my backend works because i have tested everything with postman.
However, i am unable to handle the creation of user (if user has not been created) and console.log my jwt to assure myself that it is working. I am strongly convinced it has to do with my react native code below.
Furthermore, the log which says "this is not working" is not being printed in google chrome as well.
-
import React from 'react';
import { StyleSheet, Platform, Image, Text, View, ScrollView } from 'react-native';
import { GoogleSignin, statusCodes, GoogleSigninButton } from 'react-native-google-signin';
import NavigationManager from './containers/TabNavigator';
import PhoneStorageManager from './assets/jwtStorageManager';
GoogleSignin.configure({
forceConsentPrompt: true,
webClientId: '<client-id>
});
export default class App extends React.Component {
constructor() {
super();
this.state = {failed: "NOOO", user: null, jwt: null};
}
async componentDidMount() {
}
signIn = async () => {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
this.setState({ failed: "SUCCESS" });
this.setState({ user: userInfo });
const resp = await fetch('<url>', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
session: {
token: userInfo.idToken,
authprovider: "google"
}
})
})
.then(response => response.json())
this.setState({ jwt: resp.jwt }, ()=> {
console.log(this.state.jwt, 'jwt');
PhoneStorageManager._storeData("key",this.state.jwt);
//so that i can use jwt for further api calls
});
console.log("this is not working");
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
// user cancelled the login flow
this.setState({ failed: "CANCELLED" });
} else if (error.code === statusCodes.IN_PROGRESS) {
// operation (f.e. sign in) is in progress already
this.setState({ failed: "PROGRESS" });
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// play services not available or outdated
this.setState({ failed: "NO AVAIL" });
} else {
// some other error happened
this.setState({error: error});
this.setState({ failed: "some other error happened" });
}
}
}
render() {
if (this.state.jwt) {
console.log(this.state.jwt);
return (
<NavigationManager JWT={this.state.jwt}/>
);
}
else
return (
<View style={styles.container}>
<Image source={require('./assets/auditlogo.png')} style={[styles.logo]} />
<GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={this.signIn}
disabled={this.state.isSigninInProgress} />
<Text style= {styles.instructions}>
Please Sign in to continue.
</Text>
</View>
);
}
}
1) User presses google sign in button
2) Fetch api to create user if new user.
3) Fetch api to create session. (this returns jwt for further api calls)
4) Further api calls which uses jwt. (How do i get the jwt to be passed down?)
Related
I am using axios for login request in my react-native app, when I login the first time, it logs in normally.
When calling the refresh token API with an invalid token I remove the user, remove the token from asyncTorage and logout.
But when I try to login again nothing happens, the app stays on the login page, and no error shows in the console.
I checked the network inspector and I saw the request going well and the response is received with the status 200 and the body is as usual, but the strange thing is that when I console.log(response) from Axios interceptor it shows undefined.
here is the refresh token code :
`
if (status === 401 && refreshToken) {
const refreshToken = await AsyncStorage.getItem(REFRESH_TOKEN_KEY);
return axios
.post('/refresh-token', { 'refresh-token': refreshToken })
.then(async data => {
await AsyncStorage.setItem(TOKEN_KEY, data.access_token);
await AsyncStorage.setItem(REFRESH_TOKEN_KEY, data.refresh_token);
await AsyncStorage.setItem(EXPIRES_IN_TOKEN_KEY, `${data.expires_in}`)
if (data.refresh_token_expires_in) {
await AsyncStorage.setItem(REFRESH_TOKEN_EXPIRY, data.refresh_token_expires_in);
}
originalConfig.headers.Authorization = `Bearer ${data.access_token}`;
console.log('refresh in axios');
return axios(originalConfig);
})
.catch(async (err) => {
await AsyncStorage.removeItem(TOKEN_KEY);
await AsyncStorage.removeItem(REFRESH_TOKEN_KEY);
await AsyncStorage.removeItem(EXPIRES_IN_TOKEN_KEY);
await AsyncStorage.removeItem(REFRESH_TOKEN_EXPIRY);
if (navigationRef.isReady()) {
navigationRef.navigate('Menu', { screen: 'Logout' });
return;
}
});
}
`
My login function :
export const loginUser = data =>
axios.post('/login', data).then(response => {
return ({
token: response.access_token,
refreshToken: response.refresh_token,
expiresIn: `${response.expires_in}`,
role: response.role,
refresh_token_expires_in: `${response.refresh_token_expires_in}` || '',
})});
Calling login:
const handleSubmit = values => {
setLoading(true);
api
.loginUser({ ...values, taxNumber: values.taxNumber.trim() })
.then(async data => {
console.log({data});
await AsyncStorage.setItem(TOKEN_KEY, data.token);
await AsyncStorage.setItem(REFRESH_TOKEN_KEY, data.refreshToken);
await AsyncStorage.setItem(EXPIRES_IN_TOKEN_KEY, data.expiresIn);
await AsyncStorage.setItem(REFRESH_TOKEN_EXPIRY, data.refresh_token_expires_in || "");
})
.catch(({ error }) => {
if (error) {
setErrorValue(error);
}
setLoading(false);
});
};
I am using react-native-fbsdk-next and followed all steps to set up Android/iOS (https://www.npmjs.com/package/react-native-fbsdk-next)
iOS works perfectly.
On android i receive the following redirect right after user clicks the LoginButton provided by the the fb sdk:
Here is my code:
<LoginButton
onLoginFinished={getOnLoginFinished()}
onLogoutFinished={() => {
console.log('logout.');
}}
/>
function getOnLoginFinished() {
return async (error, result) => {
let userAccessToken;
LoginManager.setLoginBehavior('native_with_fallback');
if (error) {
console.log('login has error: ' + result.error);
} else if (result.isCancelled) {
console.log('login is cancelled.');
} else {
AccessToken.getCurrentAccessToken()
.then(data => {
setUserAccessToken(data.accessToken.toString());
console.log(data.accessToken.toString());
console.log(result.grantedPermissions);
console.log(JSON.stringify(result));
})
.catch(err => {
console.log(`Get current access token, err ${err}`);
});
}
};
}
Expected deprecation, more detail here:
https://developers.facebook.com/docs/facebook-login/android/deprecating-webviews
Along with potential solution.
I am using expo-payments-stripe API for the payment of an android app. And Stripe payment API is getting called from the following firebase function:
exports.payWithStripe = functions.https.onRequest((request, response) => {
stripe.charges.create({
amount: request.body.amount,
currency: request.body.currency,
source: request.body.token,
}).then((charge) => {
response.send(charge);
})
.catch(err =>{
console.log(err);
});
});
Here is the code for the client-side that calls the firebase functions:
payment = async () => {
if (this.state.token) {
fetch(
"https://us-central1-<>.cloudfunctions.net/payWithStripe",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: this.state.amount,
currency: "usd",
token: this.state.token.tokenId,
}),
}
)
.then((response) => response.json())
.then((responseJson) => {
if (
responseJson.status === "succeeded" &&
responseJson.paid == true
) {
this.setState({ status: "succeeded", loading: false });
}
console.log(responseJson);
})
.catch((error) => {
this.setState({ status: "failed", loading: false });
console.error(error);
});
}
};
doPayment = async () => {
const params = {
number: this.state.number,
expMonth: parseInt(this.state.expMonth),
expYear: parseInt(this.state.expYear),
cvc: this.state.cvc,
};
const token = await Stripe.createTokenWithCardAsync(params);
this.setState({ token: token, loading: true });
setTimeout(() => {
this.payment();
}, 5000);
console.log(token);
};
Everything works fine in the test mode. But after deploying the app to the Play store Firebase function is not triggered. Any suggestions on why this might be happening? Also without ejecting expo what other options do I have to make payments from expo react native app for android?
Can you check adding await to the fetch or removing async from the payment function? Also why did you add setTimeout to the payment function call?
I am working on react native application and want to integrate the Phone masking feature like Uber do. I have choosen Twilio Phone Masking for this. I have used react-native-twilio-programmable-voice package.
I have integrated this using this link:: https://medium.com/#edzh1/create-a-twilio-voip-calls-in-a-react-native-app-35a729a9613d
I have done server setup successfully, using php. But getting error deviceNotReady error : "Registration failed". I have no idea what I am doing wrong here.
This is initial function I am calling here::
initTwilio = async () => {
const token = await this.getAuthToken();
if (Platform.OS === 'android') {
await this.getMicrophonePermission();
}
const success = await TwilioVoice.initWithToken(token);
if (success.initialized) {
TwilioVoice.addEventListener('deviceReady', () => {
this.setState({ twilioInited: true });
});
TwilioVoice.addEventListener('deviceNotReady', function (data) {
console.log('data', data) // getting error here
});
if (Platform.OS === 'ios') { //required for ios
TwilioVoice.configureCallKit({
appName: 'ReactNativeTwilioExampleApp',
});
}
}
};
getAuthToken = () => {
return fetch('https://myurl/accessToken.php', {
method: 'get',
})
.then(response => response.text())
.catch((error) => console.error(error));
}
Please help, and suggest me what I am doing wrong here.
I want to send sms to multiple numbers without opening to default messaging app.
I try to use react-native-sms-x but its not maintained and my project just stuck at compiling.
Also I used react-native-sms but it open default Messaging App filled with one user number and message body and had to click send button of it too.
import { Linking,Platform } from "react-native";
const url = (Platform.OS === 'android')
? 'sms:919999999999?body=your message'
: 'sms:919999999999'
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log('Unsupported url: ' + url)
} else {
return Linking.openURL(url)
}
}).catch(err => console.error('An error occurred', err))
After a lot of research and trials in the react app...
I have found this library working fine and reached the goals to send a message without going into the default message environment.
var phoneNumbers = {
"addressList": ["+911212121212", "+911212121212"]
};
var message = "This is automated test message"
SmsAndroid.autoSend(
phoneNumbers,
message,
(fail) => {
console.log('Failed with this error: ' + fail);
},
(success) => {
console.log('SMS sent successfully');
},
);
I hope it helps you. Do not forget to upvote
From Now Just For Android I use react-native-sms-android
Here is my Code for Sending sms to multiple users:
import Asms from "react-native-sms-android";
type Props = {};
export default class App extends Component<Props> {
constructor(Props) {
super(Props);
this.state = { FileNumbers: ['687867867867','8575774433'], Message:
"gjjgjgj" };
}
sendingSms = (Receivers, Messagex) => {
try {
Receivers.map(
async Numbers =>
await Asms.sms(Numbers, Messagex, "sendDirect", (err,message)
=> {
if (err) {
console.log(err);
} else {
console.log(message);
}
})
);
} catch (e) {
alert("" + e);
}
};
render() {
return (
<View style={styles.container}>
<TextInput
style={{
height: 40,
borderColor: "gray",
borderWidth: 1,
width: "90%"
}}
onChangeText={Message => this.setState({ Message })}
value={this.state.Message}
/>
<Button
title="SEND"
onPress={() =>
this.sendingSms(this.state.FileNumbers, this.state.Message)
}
/>
</View>
);
}
}