I have been trying the whole day to get Google authentication to work with React, but after searching for hours trying everything i found i only get a buggy, sometimes-working, mess. Can anyone see what i am doing wrong? (This is for a school project so i'm learning!)
The project will be an online schedule creator.
My main Index.js has the following render-function:
function renderApp() {
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={Login}></Route>
<Route component={AuthUserContainer}>
<Route path="/auth" component={Layout}>
<IndexRoute component={Overview}></IndexRoute>
<Route path="schedule(/:scheduleid)" component={Schedule}></Route>
</Route>
</Route>
</Router>,
app);
}
The home-page is simply a login page, handled by the Login component which will redirect the user to /auth if the authentication is successful. Authentication is continually handled by AuthUserContainer everytime a protected route is accessed.
The Login component has the Google Sign In button, and all protected routes has (via Layout component) a Google Sign Out button.
My Header.js contains the "Google Sign Out button" (signOutHandler):
export default class Header extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.SignOutHandler = this.SignOutHandler.bind(this);
}
SignOutHandler() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
Authenticate.signOutUser();
});
}
render() {
return (
<div class="header-content">
<h2 class="header-title">Schedule</h2>
<h3 class="header-user-button">
<a href="/" onClick={this.SignOutHandler}>User First Name</a>
</h3>
</div>
);
}
}
I used Googles own example code and tried to tweak it for React. Problems i get with this code is "Uncaught TypeError: Cannot read property 'getAuthInstance' of undefined". Since i split the Sign In and Sign Out buttons to separate pages auth2 doesn't get initialised properly, but clicking the button twice can make it work. Trying to initialise it manually here often gives me the error that Gapi is undefined...
Finally the Login.js:
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.onSignIn = this.onSignIn.bind(this);
this.renderGoogleLoginButton = this.renderGoogleLoginButton.bind(this);
}
renderGoogleLoginButton() {
console.log('rendering google signin button')
gapi.signin2.render('my-signin2', {
'scope': 'https://www.googleapis.com/auth/plus.login',
'width': 200,
'height': 50,
'longtitle': true,
'theme': 'light',
'onsuccess': this.onSignIn
});
gapi.load('auth2', function() {
gapi.auth2.init();
});
}
componentDidMount() {
window.addEventListener('google-loaded', this.renderGoogleLoginButton);
}
onSignIn(googleUser) {
Authenticate.signInUser(googleUser.getBasicProfile());
this.props.router.push("/auth");
}
render() {
return (
<div class="container">
<h2 class="form-signin-heading">
Sign-in with Google account required
</h2>
<div id="my-signin2"></div>
</div>
);
}
}
I based this code also on Googles own, but that didn't work at all (either the button didn't load, simply nothing showed, or it never called onSignIn). I also found and tried this, which made it kinda work (sometimes). I also tried to initialise auth2 in renderGoogleLoginButton(), but that only works sometimes aswell...
renderGoogleLoginButton() is called by the even-handler of a custom event (google-loaded) which fires when the Google API loads (exactly like in the link). Authenticate is my own class which bundles together my creation of token, getUserName functions etc.
I also get the following error from gapi: "Uncaught TypeError: Cannot read property 'style' of null", i think it tries to reference the Sign In/ Sign Out buttons but since they aren't loaded at the time they are null.
I cannot find any good solutions that doesn't result in glitches or bugs. Googles own code places everything in the same HTML-document, but since i want to split it up into components then it all breaks. Am i doing this completly wrong perhaps? I'm very new to React but hopefully it's understandable!
Sorry for the long post, thank you so much for your time, and if you have any questions just ask!