Mr Jax
Mr Jax

Reputation: 1017

Cloud Functions: Resized images not loading

I am following a tutorial to resize images via Cloud Functions on upload and am experiencing two major issues which I can't figure out:

1) If a PNG is uploaded, it generates the correctly sized thumbnails, but the preview of them won't load in Firestorage (Loading spinner shows indefinitely). It only shows the image after I click on "Generate new access token" (none of the generated thumbnails have an access token initially).

2) If a JPEG or any other format is uploaded, the MIME type shows as "application/octet-stream". I'm not sure how to extract the extension correctly to put into the filename of the newly generated thumbnails?

export const generateThumbs = functions.storage
.object()
.onFinalize(async object => {
  const bucket = gcs.bucket(object.bucket);
  const filePath = object.name;
  const fileName = filePath.split('/').pop();
  const bucketDir = dirname(filePath);

  const workingDir = join(tmpdir(), 'thumbs');
  const tmpFilePath = join(workingDir, 'source.png');

  if (fileName.includes('thumb@') || !object.contentType.includes('image')) {
    console.log('exiting function');
    return false;
  }

  // 1. Ensure thumbnail dir exists
  await fs.ensureDir(workingDir);

 // 2. Download Source File
 await bucket.file(filePath).download({
   destination: tmpFilePath
 });

// 3. Resize the images and define an array of upload promises
 const sizes = [64, 128, 256];

 const uploadPromises = sizes.map(async size => {
  const thumbName = `thumb@${size}_${fileName}`;
  const thumbPath = join(workingDir, thumbName);

  // Resize source image
   await sharp(tmpFilePath)
    .resize(size, size)
    .toFile(thumbPath);

  // Upload to GCS
  return bucket.upload(thumbPath, {
    destination: join(bucketDir, thumbName)
  });
});

// 4. Run the upload operations
  await Promise.all(uploadPromises);

// 5. Cleanup remove the tmp/thumbs from the filesystem
  return fs.remove(workingDir);
  });

Would greatly appreciate any feedback!

Upvotes: 3

Views: 1896

Answers (3)

ponnex
ponnex

Reputation: 848

November 2020

In connection to @Somebody answer, I can't seem to find ext-storage-resize-images-generateResizedImage in GCP Cloud Functions

The better way to do it, is to reuse the original file's firebaseStorageDownloadTokens

this is how I did mine

functions
    .storage
    .object()
    .onFinalize((object) => {

      // some image optimization code here
      // get the original file access token
      const downloadtoken = object.metadata?.firebaseStorageDownloadTokens;
      return bucket.upload(tempLocalFile, {
        destination: file,
          metadata: {
            metadata: {
              optimized: true, // other custom flags
              firebaseStorageDownloadTokens: downloadtoken, // access token
            }
            
      });
    });

Upvotes: 1

Somebody
Somebody

Reputation: 733

I just had the same problem, for unknown reason Firebase's Resize Images on purposely remove the download token from the resized image

to disable deleting Download Access Tokens

  • goto https://console.cloud.google.com
  • select Cloud Functions from the left
  • select ext-storage-resize-images-generateResizedImage
  • Click EDIT
  • from Inline Editor goto file FUNCTIONS/LIB/INDEX.JS
  • Add // before this line (delete metadata.metadata.firebaseStorageDownloadTokens;)
  • Comment the same line from this file too FUNCTIONS/SRC/INDEX.TS
  • Press DEPLOY and wait until it finish

note: both original and resized will have the same Token.

Upvotes: 8

Alvaro
Alvaro

Reputation: 117

I just started using the extension myself. I noticed that I can't access the image preview from the firebase console until I click on "create access token" I guess that you have to create this token programatically before the image is available.

I hope it helps

Upvotes: 1

Related Questions