React Hooks With Google Fit API, a Perfect Javascript Marriage

Uddeshya Singh
The Startup
Published in
7 min readAug 12, 2020

Exploring Google Fit API with Google OAuth-2 Authentication with React Hooks in a fun Javascript side project.

Want to pick your react hook and API integration skills up a notch? The following project: Fit Me Up! is a boredom brainchild that utilizes the above-mentioned technologies at its core and I have elucidated on what all did I learn throughout the development of this project!

What is Fit Me Up and who can use it? 🤔

It’s a mini visualization dashboard which fetches your weekly google fit data and gives you a summary of the following points

  • Move Minutes
  • Heart Points
  • Calories Burnt
  • Distance Travelled

Here’s the online demo!

dashboard view for the application

To give a meaningful result, you must have a Google Fit app installed in your android app / you must allow your android watch to track your location details, only then these data points will actually be recorded and you will be accessing it in the Fit Me Up dashboard by logging into your google account.

What is the Tech Stack? 💻

  • Google Fit and Google OAuth2 APIs
  • CRA Template
  • React Hooks
  • Universal Cookies
Version 1 release details

Relevant Project Links 🔗

Don’t want to read all the good points and wanna jump straight to the project? No issues. Here are the relevant links you might find helpful:

Github Repository: https://github.com/uds5501/fitmeup-oauth-visualizer

Live Demo: http://fitmeup.netlify.com/

Implementation Details✨

Wow, you are still here! Okay, in that case, lemme give you the good stuff. The important takeaways are listed below and I will be covering the one by one:-

  1. Integrating Google OAuth 2 with React Hooks
  2. Using Cookies to persist the authentication
  3. Fetching week-long data from Google Fit.

So let’s now move on to these implementations one by one (PS: the charting details will buff up this post and I really don’t want to clutter a lot into this one, so let’s focus on the workflow of how the data is passed around and processed into your app)

Integrating Google OAuth 2 with React Hooks 👨‍🏫

Fit Me Up is a visualization dashboard, so it surely needs data to visualize. Now, I need data of a specific user to fetch from Google Fit API. To point that specific user, I need his credentials and access token, so how do we get that?
The answer is simple, authentication.

I utilized react-google-login npm package to streamline my authentication process. All I needed to do here was set a react-state which stores whether my user has logged in or not and the access token. In our application, this access token is of paramount importance and happens to be the very reason why we are implementing the authentication in the first place, the get this access token.

To use the react-google-login, all I did was create two login and logout handlers, define the scope of the information I will be asking from the users and that’s it!

helper functions for authentication

The useEffect, SetCookie and DeleteCookie should be ignored for now, apart from that, login and logout functions handle their respective roles and the other two functions handle the Failure in login and logout. During login, I am setting my user state to store the information from response and set haslogin to true.

usage of react-google-login

The image above specifies how the GoogleLogin and GoogleLogout were utilized to achieve our authentication button. In the GoogleLogin button, you will have to put in a CLIENT_ID (from your google OAuth2 dashboard) and specify the scope of information you want apart from the normal details of the user.

Using Cookies to persist the authentication 🍪

Yippee! You complete the authentication, your user is logged in, now you hit refresh to celebrate but wait, why is it showing “Login”, didn’t I just log in?

A refresh means your app will reload, which simply means that you just lost all your data and hence you lost the access token, so… you gotta login again and again whenever you hit refresh or your token expires. Tedious, right?

To fix this, we need to store the user authentication details somewhere permanent, Database? sounds like an overkill. How about the browser’s local storage or Cookies? I went with cookies and let me tell you why.

By the way, why cookies?

Cookies are made exactly for this purpose, to store the user details so that user doesn’t have to re-identify itself and the app can serve him/her relevant information. Also, as a 🍒cherry on top, you can set the cookies to expire after a certain time. Now note that your access token will expire in 60 minutes, so let’s make sure our stored user data expires in 60 minutes too! This can be achieved via Cookies quite easily.

cookie manager utility

I used universal-cookie to handle the cookie implementation part. The SetCookie function saves cookies for multiple user fields which we get on authentication. Delete Cookie function deletes them while the hasCookie() function reads the user information on each app reload so that we can determine whether a user had logged in or not.

This implementation in your base app makes sure that on each reloads, your app doesn’t revert back to an unauthenticated state.

Fetching week-long data from Google Fit 🏃‍♀️

Now, our app is stable in terms of reloads, so let’s move on to the next part which is fetching the data from Google Fit Servers. They have an amazing REST API and you can read up its documentation right here.

In an HTTP request, there are headers and a request body which specifies what data do we exactly want from the serving endpoint. For that, I implemented the following helpers to get me a header and request body on the go.

An important thing to note about the request body, I am planning to request information for 7 days, and I want the data of a particular day to be kept in a particular bucket. For that, I am specifying in my request that I want the data “bucketByTime” and that too into durations of 86400000 milliseconds (24 hours)

We are using the 4 data calls precisely to store the 4 data points I want to display. Now, each such call is made asynchronously utilizing our classic axios .then() patterns.
Here I want to draw your attention to certain important questions one must ask in this implementation.

What are cookies doing here? 🔁

I am using a state (let’s say Dashboard state) which will store all this processed data inside the app. Now, your request body will change every millisecond (due to your current time being changed on each reload), so your response body will be changing every millisecond too, this will mean your Dashboard state is never the same and the application will ask to auto-refresh itself every millisecond and will be stuck in an infinite reload.

To tackle this, I am using a cookie which stores when was the last time we fetched these details from the API and we won’t keep fetching them again until the cookie expires.

This solves your infinite Dashboard reload problem.

What is that callback(state) over there? 🤯

Callback() functions are a charm.
Suppose you have to change your parent component’s state according to the properties of certain data in your child component, then how would you do that?
Voila, use callback functions. Let me show you what I did here.

This is what’s happening when your parent function loads, what it says is set any array passed into the function named “state” should be set as weekData state, and we pass this callBack function into the getWeeklyData function which is a utility function.

Now once all the processing is done, and all the promises are resolved, we call our callBack() function and set the Dashboard state to this newly processed array.
This, my friend, is the beauty of the callback() functions.

Conclusion of data processing workflow ⏳

I know, I know, it was long and descriptive, but really that was the entire point, to make it long and descriptive! This was the core of how data is fetched and passed around between utility functions and main components!
You can look up the code in the Github Repository link given above and it’s descriptive enough to show how it all fits in the actual application.

Resources

--

--

Uddeshya Singh
The Startup

Software Engineer @Gojek | GSoC’19 @fossasia | Loves distributed systems, football, anime and good coffee. Writes sometimes, reads all the time.