Google Drive API files.get does not fetch "imageMediaMetadata" for files larger than 170/180 mb

64 Views Asked by At

I'm coding an application where I use GAPI for getting my Google Drive files links and metadata. I have a specific problem where some of my files I get from files.get with passed fileId does not return their imageMediaMetadata object (width is 0, height is 0). It seems that these files that does not get their metadata has also unavailable preview in the browser or using webViewLink. Is there any flag or anything I can configure to sort this out or Google Drive just won't let me do it?

Code I'm using in Angular / TypeScript

GoogleDriveService:

@Injectable({
  providedIn: 'root',
})
export class GoogleDriveService {
  private gapiInited = false;

  private readonly googleApiScriptUrl = 'https://apis.google.com/js/api.js';
  private readonly googleDriveApiName = 'client';
  private readonly DiscoveryDoc = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

  private readonly requestedFields = 'id,name,thumbnailLink,imageMediaMetadata,webContentLink';

  constructor() {
    this.loadScript();
  }

  public initGoogleDriveClient(): void {
    gapi.load(this.googleDriveApiName, () => this.initializeGapiClient());
  }

  public async initializeGapiClient() {
    await gapi.client.init({
      apiKey: environment.googleApiKey,
      discoveryDocs: [this.DiscoveryDoc],
    });
    this.gapiInited = true;
  }

  public async getFile(fileId: string): Promise<gapi.client.drive.FileResource> {
    if (!this.gapiInited) {
      throw new Error('Google Drive client is not initialized.');
    }

    const file = await gapi.client.drive.files.get({ fileId: fileId, fields: this.requestedFields });
    return file.result;
  }

  private loadScript(): void {
    // Load the Google Picker API from the Google Developer Console
    const googleApiScript = document.createElement('script');
    googleApiScript.src = this.googleApiScriptUrl;
    googleApiScript.onload = () => {
      gapi.load(this.googleDriveApiName, () => {
        this.gapiInited = true;
        this.initGoogleDriveClient();
      });
    };

    document.body.appendChild(googleApiScript);
  }
}

Example use:

protected onGooglePickerDocumentsSelected(documents: google.picker.DocumentObject[]): void {
    const imagesFormArray = this.formGroup?.controls.images;

    if (!imagesFormArray) {
      console.error('Images FormArray is not found in the formGroup');
      return;
    }

    const getFileTasks = new Array<Promise<void>>();

    documents.forEach((document: google.picker.DocumentObject) => {
      const imageFormGroup: FormGroup<ControlsOf<ProjectImage>> = ProjectForm.createProjectImageFormGroup({
        url: document['url'],
        googleFileId: document['id'],
        designationType: this.selectedImageDesignationType,
        name: document['name'],
        width: 0,
        height: 0,
      });

      imagesFormArray.push(imageFormGroup);

      const getFileTask = this.googleDriveService.getFile(document['id']).then((file) => {
        const imageWidth = file.imageMediaMetadata?.width;
        const imageHeight = file.imageMediaMetadata?.height;

        if (imageWidth && imageHeight) {
          imageFormGroup.get('width')?.setValue(imageWidth);
          imageFormGroup.get('height')?.setValue(imageHeight);
        } else {
          console.error('Image width or height is not found');
        }
      });

      getFileTasks.push(getFileTask);
    });

    Promise.all(getFileTasks).finally(() => {
      this._validateImageSizes.next();
      this.changeDetector.detectChanges();
    });
  }

I get DocumentObject model from Google Picker API, where the google fileId is present and I got it for every file. I'm only getting no imageMediaMetadata when the file on Google Drive is too big for the preview (at least that's what I've noticed). If the file is like 160mb and the preview on Google Drive works it correcly fetches imageMediaMetadata for the file.

0

There are 0 best solutions below