Skip to main content
Check out bidbear.io Automated Amazon Reports 🚀

React-Redux: Google OAuth User ID 👮‍♀️

Intro

In order to differentiate between our users inside of our Twitch Clone, we are going to use their Google ID Number. We can get this number with GAPI using the following process.

Getting the User ID

Once a user is logged in we can retrieve their user ID using GAPI with the following request.

gapi.auth2.getAuthInstance().currentUser.get().getId()

user ID in console

Of course that is just in the console, we need to request this number and track it with state inside of our application.

Saving UserId to State with Redux

We have already setup redux to track the "Signed In" status of the user, now we need to add an additional piece of state.

Currently in our component, after the component loads we start listening for changes to the authentication status of the user. If the authentication status changes, we trigger the onAuthChange function. Depending on whether isSignedIn is true or false we will trigger one of two actions, sign in, or sign out.

If we are signing in, we also now want to retrieve the userID. So we can simply add that request as an argument in the signIn() function, and then manage that in the action later.

components/GoogleAuth.js
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux";

import { signIn, signOut } from "../actions";

class GoogleAuth extends Component {

componentDidMount() {
window.gapi.load("auth2", () => {
window.gapi.auth2
.init({
client_id: process.env.REACT_APP_GOOGLE_OAUTH2_CLIENT_ID,
scope: "email",
})
.then(() => {
// create auth variable
this.auth = window.gapi.auth2.getAuthInstance();
// update state so that component will re-render
this.onAuthChange(this.auth.isSignedIn.get());
// listen for changes to authentication status
this.auth.isSignedIn.listen(this.onAuthChange);
});
});
}

// triggered when authentication status changes
onAuthChange = (isSignedIn) => {
if (isSignedIn) {
this.props.signIn(this.auth.currentUser.get().getId()); // highlight-line
} else {
this.props.signOut();
}
};

// manually trigger GAPI auth change
onSignInClick = () => {
this.auth.signIn();
};

onSignOutClick = () => {
this.auth.signOut();
};

// helper function
renderAuthButton() {
if (this.props.isSignedIn === null) {
return null;
} else if (this.props.isSignedIn) {
return (
<button onClick={this.onSignOutClick} className="ui red google button">
<i className="google icon" />
Sign Out
</button>
);
} else {
return (
<button onClick={this.onSignInClick} className="ui red google button">
<i className="google icon" />
Sign In
</button>
);
}
}

render() {
return (
<Link to="/" className="item">
<div>{this.renderAuthButton()}</div>
</Link>
);
}
}

const mapStateToProps = (state) => {
return { isSignedIn: state.auth.isSignedIn };
}

export default connect(mapStateToProps, { signIn, signOut })(GoogleAuth);

then in our action we can receive that user ID as an argument, and add it as a payload in our action.

actions/index.js
import { SIGN_IN, SIGN_OUT } from './types'

export const signIn = (userId) => { // highlight-line
return {
type: SIGN_IN,
payload: userId // highlight-line
};
};

export const signOut = () => {
return {
type: SIGN_OUT,
};
};

Which then gets sent to the reducer, where the user id is received off the payload and is added as a piece of state in the store.

reducers/authReducer.js
import { SIGN_IN, SIGN_OUT } from '../actions/types'

const INITIAL_STATE = {
isSignedIn: null,
userId: null // highlight-line
};

export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case SIGN_IN:
return {...state, isSignedIn: true, userId: action.payload }; // highlight-line
case SIGN_OUT:
return {...state, isSignedIn: false };
default:
return state;
}
};

Lastly, we want to make sure that when the user signs out we set the user ID back to null. So we can simply add that to the SIGN_OUT reducer.

reducers/authReducer.js
import { SIGN_IN, SIGN_OUT } from '../actions/types'

const INITIAL_STATE = {
isSignedIn: null,
userId: null
};

export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case SIGN_IN:
return {...state, isSignedIn: true, userId: action.payload };
case SIGN_OUT:
return {...state, isSignedIn: false, userId: null }; // highlight-line
default:
return state;
}
};

GitHub Repo

Ncoughlin: React-Streams-Client

Automated Amazon Reports

Automatically download Amazon Seller and Advertising reports to a private database. View beautiful, on demand, exportable performance reports.

bidbear.io
bidbear-application-screenshot