Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload a file to the Google Drive API in status 200, but where's the file?

I'm trying to upload a file to Google Drive. After I run the program, I get status 200 but I can't find the file in Drive. I entered a folder ID in the fileMetadata variable under the parents key.

This is my code:

const { google } = require('googleapis');
const credentials = require('./credentials.json');
const fs = require('fs')

const scopes = [
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/drive.file',
    'https://www.googleapis.com/auth/drive.appdata',
  ];

const auth = new google.auth.JWT(
credentials.client_email, null,
credentials.private_key, scopes
);

const drive = google.drive({ version: "v3", auth });

auth.authorize(function(err, tokens) {
    if (err) {
        console.log(err);
        return;                                                     
    } else {
        console.log('It authorized successfully!');
        console.log(`The Token is: ${JSON.stringify(tokens)}`)
        var data = fs.createReadStream('./Test.txt')
        var fileMetadata = {
            'name': 'photo.txt',
            'parents':[{'id':'1MiFB-XXWFRHjxZwTmE9FxsCGb9Een_2Y'}] //Folder ID
          };
          var media = {
            mimeType: 'text/plain',
            body: data //
          };
          drive.files.create({
             resource: fileMetadata,
             media: media,
             fields: 'id'
          }).then (function(err, file) {
            if(err) {
              // Handle error
              console.log(err);
            } else {
              console.log('File Id: ', file.id);
            }
          });
    }
});

And that's the response I got back:

{
  config: {
    url: 'https://www.googleapis.com/upload/drive/v3/files?fields=id&uploadType=multipart',
    method: 'POST',
    paramsSerializer: [Function (anonymous)],
    data: PassThrough {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _flush: [Function: flush],
      [Symbol(kCapture)]: false,
      [Symbol(kTransformState)]: [Object]
    },
    headers: {
      'Content-Type': 'multipart/related; boundary=7b25465c-4ee3-450d-b41c-7efd51e4637d',
      'Accept-Encoding': 'gzip',
      'User-Agent': 'google-api-nodejs-client/0.7.2 (gzip)',
      Authorization: 'Bearer `TOKEN`,
      Accept: 'application/json'
    },
    params: [Object: null prototype] { fields: 'id', uploadType: 'multipart' },
    validateStatus: [Function (anonymous)],
    body: PassThrough {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _flush: [Function: flush],
      [Symbol(kCapture)]: false,
      [Symbol(kTransformState)]: [Object]
    },
    responseType: 'json'
  },
  data: { id: '1up-LCc9Fc0D2_t7OdJvF9D2QEVwxhV8y' },
  headers: {
    'alt-svc': 'h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
    'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
    connection: 'close',
    'content-length': '47',
    'content-type': 'application/json; charset=UTF-8',
    date: 'Mon, 27 Jul 2020 09:54:42 GMT',
    expires: 'Mon, 01 Jan 1990 00:00:00 GMT',
    pragma: 'no-cache',
    server: 'UploadServer',
    vary: 'Origin, X-Origin',
    'x-guploader-uploadid': 'AAANsUma96bf0mAHkz32b8QuarZvQBuez_rVwOmhVV-ESgd1IccLyYYnn3xdT--jVFDdo9zC9Qz_VqAVyaHK-OcQWFA'
  },
  status: 200,
  statusText: 'OK'
}

Where is the file? What's not right here?

Thank you!!

like image 450
Salvador Avatar asked Oct 24 '25 04:10

Salvador


1 Answers

I believe your goal and situation as follows.

  • You want to upload a file to Google Drive using the service account.
  • You have already been able to upload the file using Drive API with googleapis for Node.js.

Modification points:

From After I run the program, I get status 200 but I can't find the file in Drive. and the service account in your script, I think that the reason of your issue is due to that the uploaded file is put to the Google Drive of the service account.

The service account is different from your Google account. So when a file is uploaded by the service account, the file is put to the Google Drive of the service account. By this, you cannot see the file on your Google Drive using the browser.

So, in order to see the file uploaded by the service account on your Google Drive, I would like to propose the following 2 patterns.

Pattern 1:

In this pattern, the file is uploaded to the folder in your Google Drive. By this, please do the following flow.

  1. Create a folder in your Google Drive.
  2. Share the created folder to the email of the service account.
    • You can see the email of service account in the credential file of the service account.
  3. Upload the file to the shared folder using the service account.
    • In this case, please use 'parents':['### folderId ###'] as Iamblichus`s comment.

By this flow, you can see the uploaded file at the shared folder in your Google Drive.

But, in your script, it is required to modify a little.

Modified script:

From:
var fileMetadata = {
    'name': 'photo.txt',
    'parents':[{'id':'1MiFB-XXWFRHjxZwTmE9FxsCGb9Een_2Y'}] //Folder ID
  };
  var media = {
    mimeType: 'text/plain',
    body: data //
  };
drive.files.create({
   resource: fileMetadata,
   media: media,
   fields: 'id'
}).then (function(err, file) {
  if(err) {
    // Handle error
    console.log(err);
  } else {
    console.log('File Id: ', file.id);
  }
});
To:
var fileMetadata = {
    'name': 'photo.txt',
    'parents':['### folderId of the folder shared with the service account ###'}] //Folder ID
  };
  var media = {
    mimeType: 'text/plain',
    body: data //
  };
drive.files
  .create({
    resource: fileMetadata,
    media: media,
    fields: "id",
  })
  .then(function (file) {
    const fileId = file.data.id;
    console.log("File Id: ", fileId);
  })
  .catch(function (err) {
    console.log(err);
  });

Pattern 2:

In this pattern, the file is uploaded to the Google Drive of the service account and the permission is created to the file for your Google account. By this, you can see the uploaded file at "Shared with me".

Modified script:

From:
var fileMetadata = {
    'name': 'photo.txt',
    'parents':[{'id':'1MiFB-XXWFRHjxZwTmE9FxsCGb9Een_2Y'}] //Folder ID
  };
  var media = {
    mimeType: 'text/plain',
    body: data //
  };
drive.files.create({
   resource: fileMetadata,
   media: media,
   fields: 'id'
}).then (function(err, file) {
  if(err) {
    // Handle error
    console.log(err);
  } else {
    console.log('File Id: ', file.id);
  }
});
To:
var fileMetadata = {
    'name': 'photo.txt',
  };
  var media = {
    mimeType: 'text/plain',
    body: data //
  };
drive.files
  .create({
    resource: fileMetadata,
    media: media,
    fields: "id",
  })
  .then(function (file) {
    const fileId = file.data.id;
    console.log("File Id: ", fileId);
    drive.permissions.create(
      {
        resource: {
          type: "user",
          role: "writer",
          emailAddress: "###",  // <--- Please set the email of your Google account.
        },
        fileId: fileId,
        fields: "id",
      },
      function (err, res) {
        if (err) {
          console.log(err);
          return;
        }
        console.log(res.data);
      }
    );
  })
  .catch(function (err) {
    console.log(err);
  });
  • In this case, the owner of the files (except for Google Docs file) uploaded by the service account cannot be changed, yet. But I believe that when the error message of You can't yet change the owner of this item. (We're working on it.) is seen, this will be achieved in the future update.

Note:

  • I could confirm that above modified script worked with [email protected].

References:

  • googleapis for Node.js
  • Permissions: create
  • Files: create
like image 162
Tanaike Avatar answered Oct 26 '25 16:10

Tanaike