Search code examples
javascriptgoogle-apigoogle-drive-apigoogle-api-js-client

Uploading a Folder to GDrive and get the Folder ID to use to upload files


Thanks for reading my question. I am working on the google drive api and can upload files from a text blob to the google drive. However, I need to add the folder ID manually and for users to use this and not get an error since they are trying to upload it into my folder. How can I create or just get a folder ID - maybe even upload to the root GDrive directory ? Any tips would be helpful.

Thanks

// Global vars
const SCOPE = 'https://www.googleapis.com/auth/drive.file';
const gdResponse = document.querySelector('#response');
const login = document.querySelector('#login');
const authStatus = document.querySelector('#auth-status');
const textWrap = document.querySelector('.textWrapper');
const addFolder = document.querySelector('#createFolder');
const uploadBtn = document.querySelector('#uploadFile');

// Save Button and Function
uploadBtn.addEventListener('click', uploadFile);

window.addEventListener('load', () => {
  console.log('Loading init when page loads');
  // Load the API's client and auth2 modules.
  // Call the initClient function after the modules load.
  gapi.load('client:auth2', initClient);
});

function initClient() {
  const discoveryUrl =
    'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

  // Initialize the gapi.client object, which app uses to make API requests.
  // Get API key and client ID from API Console.
  // 'scope' field specifies space-delimited list of access scopes.
  gapi.client
    .init({
      apiKey: 'My-API-Key',
      clientId:
        'My-Client-ID',
      discoveryDocs: [discoveryUrl],
      scope: SCOPE,
    })
    .then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);


// Actual upload of the file to GDrive
function uploadFile() {
  let accessToken = gapi.auth.getToken().access_token; // Google Drive API Access Token
  console.log('Upload Blob - Access Token: ' + accessToken);

  let fileContent = document.querySelector('#content').value; // As a sample, upload a text file.
  console.log('File Should Contain : ' + fileContent);
  let file = new Blob([fileContent], { type: 'application/pdf' });
  let metadata = {
    name: 'Background Sync ' + date, // Filename
    mimeType: 'text/plain', // mimeType at Google Drive

    // For Testing Purpose you can change this File ID to a folder in your Google Drive
    parents: ['Manually-entered-Folder-ID'], // Folder ID in Google Drive
     // I'd like to have this automatically filled with a users folder ID
  };

  let form = new FormData();
  form.append(
    'metadata',
    new Blob([JSON.stringify(metadata)], { type: 'application/json' })
  );
  form.append('file', file);

  let 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(
      'Upload Successful to GDrive: File ID Returned - ' + xhr.response.id
    ); // Retrieve uploaded file ID.
    gdResponse.innerHTML =
      'Uploaded File. File Response ID : ' + xhr.response.id;
  };
  xhr.send(form);
}

I didn't include some of the unrelated stuff. I have something like this for the uploading of a folder and it's not working unsurprisingly.

function createFolder() {
  var fileMetadata = {
    name: 'WordQ-Backups',
    mimeType: 'application/vnd.google-apps.folder',
  };
  drive.files.create(
    {
      resource: fileMetadata,
      fields: 'id',
    },
    function (err, file) {
      if (err) {
        // Handle error
        console.error(err);
      } else {
        console.log('Folder Id: ', file.id);
      }
    }
  );
}

Solution

  • I believe your goal as follows.

    • You want to upload a file to the root folder or the created new folder.

    For this, how about the following modification patterns?

    Pattern 1:

    When you want to put the file to the root folder, please try the following modification.

    From:

    parents: ['Manually-entered-Folder-ID'],
    

    To:

    parents: ['root'],
    

    or, please remove parents: ['Manually-entered-Folder-ID'],. By this, the file is created to the root folder.

    Pattern 2:

    When you want to create new folder and put the file to the created folder, please try the following modification. In your script, unfortunately, I'm not sure about drive in createFolder() from your question. So I cannot understand about the issue of your createFolder(). So in this pattern, the folder is created with XMLHttpRequest.

    Modified script:

    function createFile(accessToken, folderId) {
      console.log('File Should Contain : ' + fileContent);
      let fileContent = document.querySelector('#content').value;
      console.log('File Should Contain : ' + fileContent);
      let file = new Blob([fileContent], { type: 'application/pdf' });
    
      let metadata = {
        name: 'Background Sync ' + date,
        mimeType: 'text/plain',
        parents: [folderId], // <--- Modified
      };
      let form = new FormData();
      form.append(
        'metadata',
        new Blob([JSON.stringify(metadata)], { type: 'application/json' })
      );
      form.append('file', file);
      
      let 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(
          'Upload Successful to GDrive: File ID Returned - ' + xhr.response.id
        );
        gdResponse.innerHTML =
          'Uploaded File. File Response ID : ' + xhr.response.id;
      };
      xhr.send(form);
    }
    
    function createFolder(accessToken) {
      const folderName = "sample"; // <--- Please set the folder name.
      
      let metadata = {
        name: folderName,
        mimeType: 'application/vnd.google-apps.folder'
      };
      let xhr = new XMLHttpRequest();
      xhr.open('post', 'https://www.googleapis.com/drive/v3/files?fields=id');
      xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.responseType = 'json';
      xhr.onload = () => {
        const folderId = xhr.response.id;
        console.log(folderId);
        createFile(accessToken, folderId);
      };
      xhr.send(JSON.stringify(metadata));
    }
    
    // At first, this function is run.
    function uploadFile() {
      let accessToken = gapi.auth.getToken().access_token;
      createFolder(accessToken);
    }
    

    Reference: