Hi I have implemented the Facebook login in my react native app. I have not used the standard button that comes with sdk. Everything work fine login is successful. But now I don't know how to extract data from Facebook user profile i.e name, email.
Below is my code
_fbAuth() {
LoginManager.logInWithReadPermissions(['public_profile']).then(function (result) {
if (result.isCancelled) {
console.log('Login was Cancelled');
} else {
const { navigate } = this.props.navigation;
//
console.log('Login Successful' + result.grantedPermissions.toString());
}
}, function (error) {
console.log('An error has occured' + error);
})
}
code for button
<TouchableHighlight onPress={() => { this._fbAuth() }}>
<Image source={require('../images/facebook-logo.png')} style={styles.facebook}></Image>
</TouchableHighlight>
You need to use AccessToken function along with the LoginManager to get the token when login is successful. After receiving the token, we can use this token to retrieve data of logged-in user using graph api of facebook.
Consider the code below:
import { LoginManager, AccessToken } from 'react-native-fbsdk';
async _fbAuth() {
let { isCancelled } = await LoginManager.logInWithReadPermissions(['public_profile','user_posts']);
if ( !isCancelled ) {
let data = await AccessToken.getCurrentAccessToken();
let token = data.accessToken.toString();
await afterLoginComplete(token);
}
else {
console.log('Login incomplete');
}
}
const afterLoginComplete = async (token) => {
const response = await fetch(
`https://graph.facebook.com/me?fields=id,name,first_name,last_name,gender,picture,cover&access_token=${token}`);
let result = await response.json();
// use this result as per the requirement
};
You can learn how to use facebook graph API from here
import {AccessToken,LoginManager} from 'react-native-fbsdk';
fbAuth() {
var current = this;
const { navigate } = this.props.navigation;
LoginManager.setLoginBehavior('web');
LoginManager.logInWithReadPermissions(['public_profile','email']).then(
function (result) {
if (result.isCancelled) {
console.log('Login was cancelled');
}
else {
//var accessToken = null;
AccessToken.getCurrentAccessToken().then(
(data) => {
console.log(data.accessToken.toString())
const{accessToken} = data
// with the help of access token you can get details for fb login
console.log('accessToken: ' + accessToken);
fetch('https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=' +accessToken)
.then((response) => response.json())
.then((json) => {
console.log('jsonn: ' + json);
console.log('Login name: ' + json.name);
console.log('Login id: ' + json.id);
console.log('Login email: ' + json.email);
var nsn = json.name
console.log('Login email state: ' +nsn);
var idfb = json.id
console.log('Login email state: ' +idfb);
var idemail = json.email
console.log('Login email state: ' +idemail);
})
.catch(() => {
reject('ERROR GETTING DATA FROM FACEBOOK')
})
})
}
},
function (error) {
console.log('Login failed with error: ' + error);
}
);
}
Related
I was using tipsi-stripe library but now i migrated it to #stripe/stripe-react-native library but i am unable to create token and get country name from card , please let me know how to implement it ,Thanks in advance.
------------------ Tipsi-stripe Code ----------------
import stripe, { PaymentCardTextField, } from 'tipsi-stripe'
stripe
.paymentRequestWithCardForm()
.then(stripeTokenInfo => {
this.state.loading = true
console.log('Token created', { stripeTokenInfo });
-------------- New Code without Create token ---------------------
import { CardField, useStripe ,confirmPayment, loading} from '#stripe/stripe-react-native';
export default class CheckoutSignin extends Component {
state = {
TotalAmount:null,
clientSecret:null
}
componentDidMount(){
console.log("Total Amount : " + this.props.route.params.TotalAmount);
this.state.TotalAmount = this.props.route.params.TotalAmount;
this.setState(this.state)
}
fetchPaymentIntentClientSecret = async () => {
makePayment(100,"AUD").then(r => {
if(r.Status === "Success"){
this.state.clientSecret = r.ClientSecret;
this.setState(this.state)
// alert("Payment Indent Success");
// console.log("1===> "+ clientSecret);
this.handlePayPress();
// console.log("3===> "+ clientSecret);
}
else {
alert("Payment Indent Failed.");
}
}).catch(e => {
alert(e)
})
};
handlePayPress = async () => {
const {paymentIntent, error} = await confirmPayment(this.state.clientSecret, {
paymentMethodType: 'Card',
paymentMethodData: {
// email: _userInfo.email,
},
});
if (error) {
console.log('Payment confirmation error', error);
Alert.alert("Error","Payment confirmation error", error);
} else if (paymentIntent) {
console.log('Success from promise', paymentIntent);
// Alert.alert("Success","Succeed Payment with 3ds");
this.props.navigation.navigate("Thankyou")
}
}
}
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 have implemented firebase phone authentication mechanism to login user with following
code:
(<any>window).FirebasePlugin.verifyPhoneNumber('+91'+this.phone, 60, function (credential) {
//alert("sms sent successfully"+ credential.verificationId);
//this.verificationId = credential.verificationId;
let modal = this.modalCtrl.create(verificationPage,{verificationId: credential.verificationId});
modal.present();
}, error => {
alert(JSON.stringify(error));
console.log("error: " + error);
});
}
but credential.verificationId value can't able to store or send to another page
verify() {
this.signInCredential = firebase.auth.PhoneAuthProvider.credential(this.verificationId, this.code);
alert("u"+JSON.stringify(this.signInCredential));
firebase.auth().signInWithCredential(this.signInCredential).then((info) => { alert("check"+JSON.stringify(info));}, (error) => {
alert("err"+JSON.stringify(error));})
}
How to resolve above error?
You should get the parameters from the nav params, directly it won't work.
try
constructor(public params: Navparams){
}
verify() {
let verificationId = params.get("verificationId");
this.signInCredential =
firebase.auth.PhoneAuthProvider.credential(verificationId, this.code);
alert("u"+JSON.stringify(this.signInCredential));
firebase.auth().signInWithCredential(this.signInCredential).then((info) =>
{
alert("check"+JSON.stringify(info));}, (error) => {
alert("err"+JSON.stringify(error));
})
}
i hope this will help you.
For your reference check this article
https://medium.com/#gbrigens/ionic-3-phone-authentication-with-firebase-dbed967e95ef
I am getting this this error. As I am already using ES6 format, That arrow but also getting same error. And somewhat confuse that how to use bind. How can I get out of this error.
code:
async fetchData() {
const { navigate } = this.props.navigation;
var DEMO_TOKEN = await AsyncStorage.getItem(STORAGE_KEY);
NetInfo.isConnected.fetch().then((isConnected) => {
if ( isConnected )
{
return fetch(`${url}`,
{
method: "GET",
headers: {
'Authorization': `JWT ${DEMO_TOKEN}`,
}
})
.then(
function(response) {
console.log(response.headers);
console.log(response.status);
console.log(response.url);
if (response.status !== 200) {
console.log('Status Code: ' + response.status);
return;
}
response.json().then((responseData) => {
console.log(responseData);
this.setState({
ver: responseData.results.appversion, // getting error here
});
});
}
)
.catch(function(err) {
console.log('Fetch Error', err);
});
Just to be clear about which this you're trying to reference, could you do this?
async fetchData() {
const ctx = this
And then reference ctx instead of this:
ctx.setState({
ver: responseData.results.appversion,
});
I have tried several times to send the data and receive a response, but it does not seem to be sending the data put in by the user. I have tried going about this in several ways,I will share the code for the last two.
ONE
state = {
phoneNo: '',
pin: '',
isLoggingIn: false,
message: ''
}
_userLogin = () => {
console.log("userLogin");
this.setState({isLoggingIn: true, message:''});
var params = {
phoneNo: this.state.phoneNo,
pin: this.state.pin
};
var proceed = false;
fetch("https://"+"<url>", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
.then(
(response) => response.json())
.then((response) => {
if (response.status == 200) {
proceed = true;
}
else {
this.setState({ message: response.message });
console.log(message); }
})
.then(() => {
this.setState({ isLoggingIn: false })
if (proceed) this.props.onLoginPress();
})
.catch(err => {
console.log(err.message);
this.setState({ message: err.message });
this.setState({ isLoggingIn: false })
});
}
Two
The only difference here is how I am handling the response so I will only add that section. I thought that the issue might be due to syntax at this point.
.then(function(response){
return response.json();
})
.then(function(data){
console.log(data)
I have been through various tutorials, github and stackoverflow pages addressing the issue but I seem to be missing something. I keep getting a JSON parse error and I am convinced that perhaps the data is never being sent to the url because I get the error regardless of user input.
Both input fields have a ref and the button points to the user login function.
<TextInput
ref = {component => this._pin = component}
placeholder="pin"
onChangeText = {(pin) => this.setState({pin})}
secureTextEntry = {true}
onSubmitEditing={this._userLogin}
/>
<TouchableOpacity
onPress={this._userLogin}
title = "Submit"
disabled={this.state.isLoggingIn||!this.state.phoneNo||!this.state.pin}>
<Text style={styles.loginText}>Sign In</Text>
</TouchableOpacity>
try something like this.
I also get problem acceding both status code & data from fetch call, so i made "processResponse" function
processResponse=(response) =>{
const statusCode = response.status;
const data = response.json();
return Promise.all([statusCode, data]).then(res => {
return ({
statusCode: res[0], // the status code
data: res[1] // the data of the GET/POST returned by fetch call
})
}
);
}
_userLogin = () => {
console.log("userLogin");
this.setState({isLoggingIn: true, message:''});
var params = {
phoneNo: this.state.phoneNo,
pin: this.state.pin
};
fetch("https://"+"<url>", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
/*processResponse return both status and data , because when you make
.then((response) => response.json()) you return only data and status is removed
*/
.then(this.processResponse)
.then(res => {
console.log("response of fetch",res);
const { statusCode, data } = res;
if (statusCode > 200) {
this.props.onLoginPress()
}else{
this.setState({ message: data.message });
console.log("data message" , data.message);
}
this.setState({ isLoggingIn: false })
})
.catch(err=> {
console.error(err);
this.setState({ message: err.message});
this.setState({isLoggingIn: false})
});
});
}
AlainIb was very helpful and this helped contribute to what worked in the end. Using form data seemed to assist with the JSON Parse error. Hope this helps anyone else who is having any troubles.
state = {
message: ''
}
_processResponse = (response) =>{
const statusCode = response.status;
console.log("resp", response);
const data = response.json();
console.log("data", data);
return Promise.all([statusCode, data]).then(res => {
return ({
statusCode: res[0], // the status code
data: res[1] // the data of the GET/POST returned by fetch call
})
});
}
_userLogin = () => {
console.log("userLogin");
this.setState({isLoggingIn: true, message:''});
var params = {
phoneno: this.state.phoneno,
pin: this.state.pin
};
var formData = new FormData();
formData.append("phoneno", this.state.phoneno);
formData.append("pin", this.state.pin);
console.log(formData);
let data = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type':'multipart/form-data'
},
body: formData
}
console.log(data);
fetch("https://"+"url", data)
.then(this._processResponse)
.then(res => {
console.log("response of fetch",res);
const { statusCode, data } = res;
if (statusCode == 200) {
console.log("in if statement");
if(data.login_success== 1){
console.log("name to be passed", data.name);
console.log("log in to profile");
this.props.navigation.navigate('ProfileRoute');
}else {
console.log("fail");
this.setState({message:"Password or Phone Number is Wrong"});
}
}else{
this.setState({ message: data.message });
console.log("data message" , data.message);
}
this.setState({ isLoggingIn: false })
})
.catch(err=> {
console.error(err);
this.setState({ message: err.message});
this.setState({isLoggingIn: false})
});
}