I am trying to implement Facebook login in my class. I created a button component, but when I call the Facebook api and I try to dispatch a register function I get un defined props. Here is my component:
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import { LoginManager, AccessToken, GraphRequest, GraphRequestManager } from 'react-native-fbsdk';
import Icon from 'react-native-vector-icons/FontAwesome';
import { connect } from 'react-redux';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {register} from '../Actions/authActions';
class Login extends Component {
constructor(props) {
super(props);
}
_fbAuth = () => {
LoginManager.logInWithPermissions(['public_profile','email']).then(function(result){
if(result.isCancelled){
console.log('loging cancelled')
}
else {
AccessToken.getCurrentAccessToken().then((data) => {
let accessToken = data.accessToken;
let facebookId = data.userID;
const responseInfoCallback = (error, result) => {
if (error) {
alert('Error logging in with Facebook');
}
else {
console.log('Props here are empty', this.props);
this.props.registerSubmit({
"customerName": result.name,
"customerTel": '000000000',
"customerEmail": result.email,
"customerPassword": facebookId
}).then(response => {
console.log('RESPONSE', response);
if (response && response.Success) {
this.props.navigation.navigate('App');
AsyncStorage.setItem('customerEmail', data.email);
AsyncStorage.setItem('customerPassword', data.password);
} else {
this.props.navigation.navigate('Auth');
}
});
}
}
const infoRequest = new GraphRequest('/me', {
accessToken: accessToken,
parameters: {
fields: {
string: 'name,picture,email'
}}
}, responseInfoCallback);
new GraphRequestManager().addRequest(infoRequest).start();
});
}}, function (error) {
console.log('Error logging with facebook');
});
}
render() {
return (
<View style={styles.container}>
<Icon.Button name="facebook" backgroundColor="#3b5998" onPress={this._fbAuth.bind(this)} style={styles.signInButton}>
Facebook login
</Icon.Button>
</View>
)
}
};
const mapDispatchToProps = (dispatch) => {
// Action
return {
// Login
registerSubmit: (data) => dispatch(register(data)),
};
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
signInButton: {
width: 358,
height: 48
}
});
export default connect(null, mapDispatchToProps)(Login);
When I get into the callback function this.props is empty and therefor the registerSubmit is undefined. This is my first project using class components I usually use hooks. What am I doing wrong?
When you run this line:
LoginManager.logInWithPermissions(['public_profile','email']).then(function(result){
The new function (result) {
scope has its own this
.
In order to access your component's this
, you can either save a reference to it outside the callback, and then use that from inside the callback:
const componentProps = this.props
LoginManager.logInWithPermissions(['public_profile','email']).then(function(result){
Or, you can use an "arrow function" for your callback, which does not have its own this
, like so:
LoginManager.logInWithPermissions(['public_profile','email']).then(result => {
(Notice how we aren't using the function
keyword anymore)