3

After I upload an image. Cloud function generate its thumbnails as specified in the concerned firebase function using sharp on typescript. But for the second image and so on, thumbnails are generated and named correctly as expected but it contains same image thumb as the first image uploaded.

First Photo : First

Thumbnail of First Photo : thumb of first

Second Photo : default

Thumbnail of second Photo : thumb of default

import * as functions from 'firebase-functions';

import * as Storage from '@google-cloud/storage';
const gcs = Storage();

import { tmpdir } from 'os';
import { join, dirname } from 'path';

import * as sharp from 'sharp';
import * as fs from 'fs-extra';

export const generateThumbs = functions.storage.object().onFinalize(async object => {
    const bucket = gcs.bucket(object.bucket);
    const filePath = object.name;
    const fileName = filePath.split('/').pop();
    console.log('filename : ' + fileName);
    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, 256, 512];

    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);
});

Expected : Unique files uploaded should result in unique thumbs and not just unique names.

Actual : Only new filenames are generated with old thumb data from previous image.

  • all your images have this error: >{ "error": { "code": 403, "message": "Permission denied. Could not perform this operation" } } – Moshe Slavin Dec 31 '18 at 10:52
  • @MosheSlavin its available now. – Sameer Kumar Dec 31 '18 at 11:26
  • Did you manage to solve this? I have the same issue. For me the file is overwritten and I suspected that might be the problem. Is that also the same as in you scenario? – avilao Jan 20 '19 at 18:05

1 Answers1

2

I think this is a caching problem here.. i added a workaround by using a uuid in tmp folder. So its not possible that there is any cached files anymore.

Install uuid package

npm i uuid

import it as global

import { Storage } from '@google-cloud/storage';
const gcs = new Storage();
const uuidv1 = require('uuid/v1');

And change the workinDir line to:

const workingDir = join(tmpdir() + '/' + uuidv1(), 'thumbs');