Intro :
I wanted to give up countless times. You never know how hopeless I was every time I found a Google Drive API tutorial video on YouTube not very helpful. Also, there're fewer related posts about how to implement Google Drive API with React. It did take me a few days to figure them out and record some important details as much as I can remember in this blog.
Google OAuth2
Using react-oauth can make your life easier.
index.js
jsx < GoogleOAuthProvider clientId = "..." >
< App />
</ GoogleOAuthProvider >
Login
jsx import { useGoogleLogin } from "@react-oauth/google" ;
const login = useGoogleLogin ({
onSuccess : async ( res ) => {
// localStorage.setItem("access_token", res.access_token);
},
onError : () => {
console. log ( "Login Failed" );
},
scope: "https://www.googleapis.com/auth/drive" ,
});
Note: Don't forget to set scope
(A space-delimited list of scopes. The type is String). Otherwise, you have no permission to use some Google APIs.
Logout
jsx import { googleLogout } from "@react-oauth/google" ;
const logout = () => {
googleLogout ();
// localStorage.removeItem("access_token");
};
Get UserInfo
jsx useEffect (() => {
if (token) {
axios
. get ( "https://www.googleapis.com/oauth2/v3/userinfo" , {
headers: { Authorization: `Bearer ${ token }` },
})
. then (( userInfo ) => {
// setUser(userInfo.data);
})
. catch (( err ) => {
// localStorage.removeItem("access_token");
console. error (err);
});
}
}, [token]);
Google Drive & Picker
Set up
Follow Drive API - JavaScript quickstart doc to set up and run an app that calls a Google Workspace API.
Get file from Google Drive
React-google-drive-picker
GoogleDrivePicker.jsx
jsx const handleOpenPicker = () => {
openPicker ({
clientId:
"..." ,
developerKey: "..." ,
viewMimeTypes: "application/json" ,
token: token,
supportDrives: true ,
callbackFunction : ( data ) => {
switch (data.action) {
case "cancel" :
console. log ( "User clicked cancel/close button" );
break ;
case "picked" :
onFileUpload (
`https://www.googleapis.com/drive/v3/files/${ data . docs [ 0 ]. id }?alt=media&key=...` ,
data.docs[ 0 ].name
);
break ;
default :
}
},
});
};
Note: You can get token
after you login succesfully.
Get file from Google Drive (In this scenario, the file I want to get is a JSON file.):
jsx const onFileUploadDrive = ( url , name ) => {
localStorage. setItem ( "cv_data_file_name" , name);
axios
. get (url, {
headers: {
Authorization: `Bearer ${ localStorage . getItem ( "access_token" ) }` ,
Accept: "application/json" ,
},
})
. then (( res ) => {
// console.log(res.data);
})
. catch (( error ) => {
console. error ( "Fetch error:" , error);
});
};
Upload file to Google Drive
References :
jsx const onSaveDrive = () => {
const token = localStorage. getItem ( "access_token" );
if (token) {
const jsonData = JSON . stringify (cvData);
const file = new File ([jsonData], fileName);
axios
. post (
`https://www.googleapis.com/upload/drive/v3/files?key=...` ,
file,
{
headers: {
Authorization: `Bearer ${ token }` ,
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
}
)
. then (( res ) => {
axios
. patch (
`https://www.googleapis.com/drive/v3/files/${ res . data . id }?key=...` ,
{
name: fileName,
description:
"This CV metadata is downloaded from cv.harriswong.top" ,
},
{
headers: {
Authorization: `Bearer ${ token }` ,
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
}
)
. then (( res1 ) => {
setIsShowSave ( false );
setOpenUpload ( true );
});
})
. catch (( error ) => {
console. error ( "Fetch error:" , error);
});
} else {
setOpenSignIn ( true );
}
};
The reason why there are two requests to be send is because I can't find a way to upload a JSON file to Goole Drive with a file name. So my strategy is upload a Untitled file to Drive and then update its file name.
Videos :
Make it public
If you want some Google API services on your deployed website to work properly, you need to make it public in OAuth consent screen .
The process of publishing your app is not very hard but troublesome. They need you to make a YouTube video to explain how to secure user data. Yeh I kinda quit. I know nobody's gonna use my web app hahah unless I advertise it.