2
votes

I have analyzed the thumbnail creation code using firebase storage trigger.

I need to resize the current image without renaming the file and it should not cause infinite loop.

Basically, whenever I am uploading the image to firebase storage, it should be resized to specific size, but, other properties like download url, name should not be changed.

Below is the code for generating thumbnail. But, I need to make it to resize the current image. Please help.

Here, if the filename is having thumb_, then only the infinite loop will stop, I need to stop it using other properties like meta data or anything

exports.generateThumbnail = functions.storage.object().onChange((event) => {
  const object = event.data; 

  const fileBucket = object.bucket; 
  const filePath = object.name; 
  const contentType = object.contentType; 
  const resourceState = object.resourceState; 
  const metageneration = object.metageneration; 

  if (!contentType.startsWith('image/')) {
    console.log('This is not an image.');
    return null;
  }

  const fileName = path.basename(filePath);
  if (fileName.startsWith('thumb_')) {
    console.log('Already a Thumbnail.');
    return null;
    //Here, if the filename is having thumb_, then only the infinite loop will stop, I need to stop it using other properties like meta data or anything else
  }

  if (resourceState === 'not_exists') {
    console.log('This is a deletion event.');
    return null;
  }

  if (resourceState === 'exists' && metageneration > 1) {
    console.log('This is a metadata change event.');
    return null;
  }

  const bucket = gcs.bucket(fileBucket);
  const tempFilePath = path.join(os.tmpdir(), fileName);
  const metadata = {
    contentType: contentType,
  };
  return bucket.file(filePath).download({
    destination: tempFilePath,
  }).then(() => {
    console.log('Image downloaded locally to', tempFilePath);
    return spawn('convert', [tempFilePath, '-thumbnail', '200x200>', tempFilePath]);
  }).then(() => {
    console.log('Thumbnail created at', tempFilePath);
    const thumbFileName = `thumb_${fileName}`;
    const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
    return bucket.upload(tempFilePath, {
      destination: thumbFilePath,
      metadata: metadata,
    });
  }).then(() => fs.unlinkSync(tempFilePath));
});
1

1 Answers

0
votes

Pass custom metadata to the upload function:

return bucket.upload(tempFilePath, {
  destination: filePath,
  metadata: {
    contentType,
    metadata: {
      isThumb: 'true',
    }
  },
})

When you replace the file, the cloud function will be triggered again. To break the loop check the custom metadata:

/**
  * File metadata.
  */
const meta = object.metadata;

/**
  * Exit if the image is already a thumbnail.
  */
if (meta && meta.isThumb == 'true') {
   console.log('Already a Thumbnail.');
   return null;
}