I've been working on integrating Google Sign-In for my application and have run into an intriguing problem. While the sign-in process is seamless and works as expected, I've noticed that upon refreshing the page, I seem to lose my connection to gapi. I still retain both the userDetails and the accessToken.
I use gapi later on in my application to fetch calendar events, and it's crucial that this connection remains intact even after a page refresh. Everything seemed to be functioning fine until I encountered this hiccup. My primary function for the Google Sign-In process seems to be the root of the problem.
import { useState, useEffect } from "react";
import { gapi } from "gapi-script";
import axios from "axios";
import { useSelector } from "react-redux";
const google = window.google;
export const useGoogleSignIn = () => {
const [googleAccessToken, setGoogleAccessToken] = useState();
const [userDetails, setUserDetails] = useState();
const { hotCredintials } = useSelector((state) => state.hotCredintials);
const apiKey = "";
const clientID = "";
const refreshToken = ""
const clientSecret = ""
useEffect(() => {
// fetchData(apiRoutes.hotCredentials).then((res) => setCredentialKeys(res));
const accessTkn = localStorage.getItem("googleAccessToken");
setGoogleAccessToken((prev) => ({
...prev,
access_token: JSON.parse(accessTkn),
}));
}, []);
const onGoogleSignIn = () => {
const timestampInMilliseconds = new Date().getTime();
/* client google */
const client = google.accounts.oauth2.initTokenClient({
client_id: hotCredintials.find(({ credentialId }) => credentialId === "3")
?.credentialValue,
scope: SCOPES,
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse?.access_token) {
setGoogleAccessToken(tokenResponse);
localStorage.setItem(
"googleAccessToken",
JSON.stringify(tokenResponse.access_token)
);
localStorage.setItem(
"googleAccessTokenExpire",
JSON.stringify(timestampInMilliseconds)
);
gapi.client.setApiKey(apiKey);
}
},
});
client.requestAccessToken();
};
const onGoogleSignOut = () => {
google.accounts.id.disableAutoSelect();
// google.accounts.oauth2.revoke(googleAccessToken.access_token);
setGoogleAccessToken("");
setUserDetails("");
localStorage.removeItem("googleAccessToken");
};
useEffect(() => {
// refresh access token before it expires
const intervalId = setInterval(() => {
const expireTime = Number(
localStorage.getItem("googleAccessTokenExpire")
);
const timeLimit = expireTime + 3580 * 1000; // Convert 3580 seconds to milliseconds and add to expireTime
const timeNow = new Date().getTime();
if (googleAccessToken.access_token && timeNow > timeLimit) {
axios
.post(`https://oauth2.googleapis.com/token`, {
client_id: clientID,
client_secret: clientSecret,
grant_type: "refresh_token",
refresh_token:
refreshToken
})
.then((res) => {
setGoogleAccessToken((prev) => {
return {
...prev,
access_token: res.data.access_token,
expires_in: res.data.expires_in,
token_type: res.data.token_type,
scope: res.data.scope,
};
});
localStorage.setItem(
"googleAccessToken",
JSON.stringify(res.data.access_token)
);
localStorage.setItem(
"googleAccessTokenExpire",
JSON.stringify(newTimestampInMilliseconds)
);
})
.catch((err) => console.log(err));
}
}, 10000); // Refresh every 10 seconds
// Cleanup function to clear the interval
return () => clearInterval(intervalId);
}, [googleAccessToken]);
useEffect(() => {
if (googleAccessToken?.access_token)
fetch(
`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${googleAccessToken.access_token}`
)
.then((response) => response.json())
.then((content) => {
setUserDetails(content);
gapi.client.setApiKey(apiKey);
})
.catch((err) => {
console.log(err);
});
}, [googleAccessToken]);
return {
onGoogleSignIn,
onGoogleSignOut,
userDetails,
};
};
Fixed by authorizing gapi