Google Drive API creating 0-byte files

170 Views Asked by At

I'm trying to create a file using the Google GDrive API using the following Node.js example from the documentation under section Perform a multipart upload:

/**
 * Insert new file.
 * @return{obj} file Id
 * */
async function uploadBasic() {
  const fs = require('fs');
  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');

  // Get credentials and build service
  // TODO (developer) - Use appropriate auth mechanism for your app
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const service = google.drive({version: 'v3', auth});
  const requestBody = {
    name: 'photo.jpg',
    fields: 'id',
  };
  const media = {
    mimeType: 'image/jpeg',
    body: fs.createReadStream('files/photo.jpg'),
  };
  try {
    const file = await service.files.create({
      requestBody,
      media: media,
    });
    console.log('File Id:', file.data.id);
    return file.data.id;
  } catch (err) {
    // TODO(developer) - Handle error
    throw err;
  }
}

Here is the actual code I'm using adapted for my project:

public async uploadToFolder(parentFolderId: string) {
    try {
        const requestBody = {
            fields: 'id',
            name: 'cat.jpg',
            parents: [parentFolderId],
        };
        const media = {
            mimeType: 'image/jpeg',
            body: fs.createReadStream(
                path.join('/Users/john/Documents/cat.jpg'),
            ),
        };
        await this.drive.files.create({
            auth: this.jwtCreds,
            supportsAllDrives: true,
            requestBody: requestBody,
            media: media,
        });

    } catch (err) {
        this.logger.error(
            `Error uploading '${fileName}' to folder ${parentFolderId}: ${err}`,
        );
        throw err;
    }
}

I am using scope ['https://www.googleapis.com/auth/drive'] while authenticating.

The file is created in the expected parent directory of the expected shared drive with the correct file name and correct file type, but the file size is 0 bytes.

I have tried passing data of type ReadStream from fs.createReadStream into media.body which yields a created file of length 0 bytes.

I have tried passing data of type Buffer from fs.readFileSync into media.body which either yeilds a created file of length 0 bytes or a file of double length, depending on how I manage the Buffer.

I have tried passing a Base64 encoded string into media.body which just yeilds a created file containing the encoded string.

I have tried passing in plain text into media.body, which yields a created file containing the plain text; seems to work as expected.

I have tried creating a folder using the method above which yields a created folder; seems to work as expected.

1

There are 1 best solutions below

0
John On

Apparently if we do a subsequent update call after create like this, it works:

const requestBody = {
    fields: 'id',
    name: 'cat.jpg',
    parents: [parentFolderId],
};

const media = {
    mimeType: 'image/jpeg',
    body: fs.createReadStream(
        path.join('/Users/john/Documents/cat.jpg'),
    ),
};

const file = await this.drive.files.create({
    auth: this.jwtCreds,
    supportsAllDrives: true,
    uploadType: 'media',
    requestBody: requestBody,
    media: media,
});

const response = await this.drive.files.update({
    auth: this.jwtCreds,
    fileId: file.data.id,
    media: {
        mimeType: 'image/png',
        body: fileData,
    },
    supportsAllDrives: true,
    uploadType: 'multipart',
});