Flutter 从云函数覆盖云存储中已调整大小的图像的错误

Flutter 从云函数覆盖云存储中已调整大小的图像的错误,flutter,google-cloud-functions,google-cloud-storage,Flutter,Google Cloud Functions,Google Cloud Storage,当前情况 我正在云存储中存储个人资料图片。每次添加/更新一个,我都想制作一个调整大小的拇指。 因此,在我的云函数中,我添加了以下触发器: import { Storage } from '@google-cloud/storage'; import * as functions from 'firebase-functions'; import * as fs from 'fs-extra'; import { tmpdir } from 'os'; import { dirname, join

当前情况

我正在云存储中存储个人资料图片。每次添加/更新一个,我都想制作一个调整大小的拇指。 因此,在我的云函数中,我添加了以下触发器:

import { Storage } from '@google-cloud/storage';
import * as functions from 'firebase-functions';
import * as fs from 'fs-extra';
import { tmpdir } from 'os';
import { dirname, join } from 'path';
import * as sharp from 'sharp';


const gcs = new Storage();

//Thumb will not override previous thumb.

export const generateThumbs = functions.region('europe-west1')
  .storage
  .object()
  .onFinalize(async object => {
    const bucket = gcs.bucket(object.bucket);


    const filePath = object.name;
    if (filePath) {
      const fileName = filePath.split('/').pop();
      if (fileName) {
        const bucketDir = dirname(filePath);

        const workingDir = join(tmpdir(), 'thumbs', Date.now().toString());
        const tmpFilePath = join(workingDir, fileName);

        if (fileName.includes('thumb@') || (object.contentType && !object.contentType.includes('image'))) {
          console.log('exiting function: ' + fileName);
          return false;
        }
        await fs.ensureDir(workingDir);

        await bucket.file(filePath).download({
          destination: tmpFilePath
        });

        const sizes = [256];

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


          await sharp(tmpFilePath)
            .resize(size, size)
            .toFile(thumbPath);

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


        await Promise.all(uploadPromises);

        return fs.remove(workingDir).then(() => {
          return fs.remove(bucketDir);
        })
      }
    }
    return null;
  });
每个用户只有一个配置文件图片,我不需要保留以前的配置文件图片,因此,例如,用户id=25,我上载了其文件名为“25.jpeg”的图像,正确创建了拇指图像“thumb_256_25.jpeg”

问题


现在,用户更改了图像,我用一个新图像覆盖了以前的“25.jpeg”(这就像预期的那样),我的云函数触发器运行。它确实在“thumb_256_25.jpeg”上上传了一个新的拇指图像。很少情况下,新上传的thumb是新上传的25.jpeg图像的实际thumb图像。更常见的情况是重新上传的不是上一个,就是更旧的。

调试非常困难,但我发现唯一可行的工作解决方案是给workingDir一个唯一的文件夹名,如下所示:

const workingDir=join(tmpdir(),'thumbs',Date.now().toString())

我用fs.remove和fs.unlink尝试了几种方法,但都不起作用。对我来说,问题是在函数运行后,workingDir、thumbPath甚至tmpFilePath文件没有正确删除。因此,在下一次运行时,夏普要么调整tmpFilePath中存在的旧图像的大小,要么调整下载的新图像的大小,但上载一个旧图像。虽然这很奇怪,因为我在函数末尾删除了那个文件夹


如果有人有解释或其他解决方案,请分享

你在你的bucket上启用了吗?没有。我想我会尝试更改最后一行,返回fs.remove为wait,然后返回null,可能是因为当我更改图片时workingdir仍然存在,它会从该dir上传上一张图片。或者,回报与等待是一样的?我知道这听起来很奇怪,但这是我唯一能想到的。如果此问题仍然存在,我将尝试使用onDelete触发器删除上一个thumb文件,然后查看它是否工作。