Reputation: 1628
I am a student learning React. I am trying to create a web app where a user must sign in with Google before viewing any of the content. I began with the code from the github-notetaker
example and have edited Main.js
. So far, I am writing the entire logic inside the init()
method and setting loggedIn
and email
values in this.state
.
import React from 'react';
import { RouteHandler } from 'react-router';
import Rebase from 're-base';
class Main extends React.Component{
constructor(props){
super(props);
this.state = {
loggedIn: props.loggedIn,
email: props.email
};
}
authDataCallback(authData) {
if (authData) {
console.log('User is already logged in.');
console.log(authData["google"]["email"]); // works as expected
this.setState({
loggedIn: true,
email: authData["google"]["email"]
});
console.log(this.state.email); // does not work as expected
} else {
this.setState({
loggedIn: false
});
console.log('Attempting to authenticate user account');
this.ref.authWithOAuthPopup('google', function (error, authData) {
if (error) {
console.log('Login Failed!', error);
} else {
console.log('Authenticated successfully');
}
}, {
scope: "email"
});
}
}
init(){
console.log('Init called');
this.ref = new Firebase('https://myapp.firebaseio.com/');
this.ref.onAuth(this.authDataCallback.bind(this));
}
componentWillMount(){
this.router = this.context.router;
}
componentDidMount(){
this.init();
}
componentWillReceiveProps(){
this.init();
}
render(){
if (!this.state.loggedIn) {
return (
<div className="main-container">
<div className="container">
<h3>You are not authenticated. <a href="">Login</a></h3>
</div>
</div>
)
} else {
return (
<div className="main-container">
<div className="container">
<RouteHandler {...this.props}/>
</div>
</div>
)
}
}
};
Main.propTypes = {
loggedIn: React.PropTypes.bool,
email: React.PropTypes.string
};
Main.defaultProps = {
loggedIn: false,
email: ''
}
Main.contextTypes = {
router: React.PropTypes.func.isRequired
};
export default Main;
I am encountering an odd bug and believe that I am doing this the wrong way. When the user authenticates successfully, all of the information is saved and the user's email
is written. Here's what the console log looks like:
User is already logged in.
[email protected] // corresponds to authData["google"]["email"]
[email protected] // corresponds to this.state.email = CORRECT!!
However, when I refresh the page, the new print looks like this, and it appears that the email and object are still available to me but are not getting saved in this.state
.
User is already logged in.
[email protected] // corresponds to authData["google"]["email"]
null
I am currently learning React and so this may be a really simple error. Thank you so much for your time and help in advance. If you could point me in the right direction or let me a know a better way to do this, I'd really appreciate it. Thanks!
Upvotes: 0
Views: 570
Reputation: 1628
I believe I found the reason for my issue. When I call the following code in render()
<h1> {this.state.email} </h1>
It works just fine. Therefore, my conclusion is that console.log(this.state.email)
is somehow run before this.setState()
is fully completed.
Upvotes: 1
Reputation: 1211
You're writing the code wrong.
var currentAuthData = this.ref.getAuth();
sends a request to fireBase to get the authentication, however the next line of code if (currentAuthData) {
is run before fireBase can retrieve the correct information.
You must use a callback function instead.
ref.onAuth(authDataCallback);
function authDataCallback(authData) {
if (authData) {
console.log('User is already logged in.');
}
}
Upvotes: 0