I am trying to store a json object that contains config info in a Google Drive Appdata file. I am currently writing the app in JS that is run on the client side. Using the Google Drive API, I can currently check for the file in the appdata folder. How would I go about generating a new file and storing it in the appdata folder if the config was not found?
var request = gapi.client.drive.files.list({
'q': '\'appdata\' in parents'
});
request.execute(function(resp) {
for (i in resp.items) {
if(resp.items[i].title == FILENAME) {
fileId = resp.items[i].id;
readFile(); //Function to read file
return;
}
}
//Create the new file if not found
});
The gapi client does not provide a method to upload files to google drive (it does for metadata) but they do still expose an API endpoint. Here's an example I've been using for the V3 api
function saveFile(file, fileName, callback) {
var file = new Blob([JSON.stringify(file)], {type: 'application/json'});
var metadata = {
'name': fileName, // Filename at Google Drive
'mimeType': 'application/json', // mimeType at Google Drive
'parents': ['appDataFolder'], // Folder ID at Google Drive
};
var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
form.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.responseType = 'json';
xhr.onload = () => {
console.log(xhr.response.id); // Retrieve uploaded file ID.
callback(xhr.response);
};
xhr.send(form);
}
And since google drive will allow duplicate filenames since they're unique by ID I use something like this to check if it exists already:
function fileExists(file, fileName){
var request = gapi.client.drive.files.list({
spaces: 'appDataFolder',
fields: 'files(id, name, modifiedTime)'
});
request.execute(function(res){
var exists = res.files.filter(function(f){
return f.name.toLowerCase() === fileName.toLowerCase();
}).length > 0;
if(!exists){
saveFile(file, fileName, function(newFileId){
//Do something with the result
})
}
})
}
Check the documentation about Storing Application Data:
The 'Application Data folder' is a special folder that is only accessible by your application. Its content is hidden from the user, and from other apps. Despite being hidden from the user, the Application Data folder is stored on the user's Drive and therefore uses the user's Drive storage quota. The Application Data folder can be used to store configuration files, saved games data, or any other types of files that the user should not directly interact with.
To be able to use your Application Data folder, request access to the following scope:
https://www.googleapis.com/auth/drive.appdata
If you'll check the sample code on how to insert a file into the Application Data folder(PHP code):
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'config.json',
'parents' => array('appDataFolder')
));
$content = file_get_contents('files/config.json');
$file = $driveService->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => 'application/json',
'uploadType' => 'multipart',
'fields' => 'id'));
printf("File ID: %s\n", $file->id);
By adding appDataFolder
as a parent for the file will make it write to the appFolder. Then implement you own uploading/cody code to insert the file and its content to the appFolder.
Hope this helps