Создать ошибку функции облака миниатюр с GCS - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть приложение, в котором я хочу создать миниатюру для каждого изображения, загруженного в хранилище.Я пытаюсь использовать облачную функцию создания миниатюр, но когда изображение загружается в хранилище, облачная функция выдает ошибку в своих журналах в firebase.

TypeError: gcs(...).bucket is not a function
    at exports.generateThumbnail.functions.storage.object.onFinalize (/user_code/index.js:77:73)
    at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23)
    at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20)
    at /var/tmp/worker/worker.js:768:24
    at process._tickDomainCallback (internal/process/next_tick.js:135:7)

Вот мой файл index.js.Здесь требуется только GCS.

const functions = require("firebase-functions");
  const gcs = require("@google-cloud/storage");
admin.initializeApp();

const THUMB_MAX_HEIGHT = 200;
const THUMB_MAX_WIDTH = 200;
// Thumbnail prefix added to file names.
const THUMB_PREFIX = 'thumb_';
exports.generateThumbnail = functions.storage.object().onFinalize((object) => {
  // File and directory paths.
  const filePath = object.name;
  const contentType = object.contentType; // This is the image MIME type
  const fileDir = path.dirname(filePath);
  const fileName = path.basename(filePath);
  const thumbFilePath = path.normalize(path.join(fileDir, `${THUMB_PREFIX}${fileName}`));
  const tempLocalFile = path.join(os.tmpdir(), filePath);
  const tempLocalDir = path.dirname(tempLocalFile);
  const tempLocalThumbFile = path.join(os.tmpdir(), thumbFilePath);

  // Exit if this is triggered on a file that is not an image.
  if (!contentType.startsWith('image/')) {
    console.log('This is not an image.');
    return null;
  }

  // Exit if the image is already a thumbnail.
  if (fileName.startsWith(THUMB_PREFIX)) {
    console.log('Already a Thumbnail.');
    return null;
  }

  // Cloud Storage files.
  const bucket = gcs({keyFilename: 'service-account-credentials.json'}).bucket(object.bucket);
  const file = bucket.file(filePath);
  const thumbFile = bucket.file(thumbFilePath);
  const metadata = {
    contentType: contentType,
    // To enable Client-side caching you can set the Cache-Control headers here. Uncomment below.
    // 'Cache-Control': 'public,max-age=3600',
  };

  // Create the temp directory where the storage file will be downloaded.
  return mkdirp(tempLocalDir).then(() => {
    // Download file from bucket.
    return file.download({destination: tempLocalFile});
  }).then(() => {
    console.log('The file has been downloaded to', tempLocalFile);
    // Generate a thumbnail using ImageMagick.
    return spawn('convert', [tempLocalFile, '-thumbnail', `${THUMB_MAX_WIDTH}x${THUMB_MAX_HEIGHT}>`, tempLocalThumbFile], {capture: ['stdout', 'stderr']});
  }).then(() => {
    console.log('Thumbnail created at', tempLocalThumbFile);
    // Uploading the Thumbnail.
    return bucket.upload(tempLocalThumbFile, {destination: thumbFilePath, metadata: metadata});
  }).then(() => {
    console.log('Thumbnail uploaded to Storage at', thumbFilePath);
    // Once the image has been uploaded delete the local files to free up disk space.
    fs.unlinkSync(tempLocalFile);
    fs.unlinkSync(tempLocalThumbFile);
    // Get the Signed URLs for the thumbnail and original image.
    const config = {
      action: 'read',
      expires: '03-01-2500',
    };
    return Promise.all([
      thumbFile.getSignedUrl(config),
      file.getSignedUrl(config),
    ]);
  }).then((results) => {
    console.log('Got Signed URLs.');
    const thumbResult = results[0];
    const originalResult = results[1];
    const thumbFileUrl = thumbResult[0];
    const fileUrl = originalResult[0];
    console.log('Got Signed URLs. '+ thumbFileUrl);
    return result;
  }).then(() => console.log('Thumbnail URLs saved to database.'));
});

Невозможно понять, в чем проблема! *

Я внес изменения в соответствии с предложением ответа

require(...) is not a function
    at Object.<anonymous> (D:\mercury_two\mercury\functions\index.js:20:45)
    at Module._compile (internal/modules/cjs/loader.js:678:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
    at Module.load (internal/modules/cjs/loader.js:589:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
    at Function.Module._load (internal/modules/cjs/loader.js:520:3)
    at Module.require (internal/modules/cjs/loader.js:626:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at C:\Users\Harsha\AppData\Roaming\npm\node_modules\firebase-tools\lib\triggerParser.js:15:15
    at Object.<anonymous> (C:\Users\Harsha\AppData\Roaming\npm\node_modules\firebase-tools\lib\triggerParser.js:53:3)

Тогда яне могу даже развернуть функцию.'firebase deploy' выдает ошибку выше.

1 Ответ

0 голосов
/ 06 декабря 2018

Вы не должны делать

const bucket = gcs({keyFilename: 'service-account-credentials.json'}).bucket(object.bucket);

, а только

const bucket = gcs.bucket(object.bucket);

Вам необходимо использовать service-account-credentials.json (то есть файл JSON ключа учетной записи службы) только тогда, когда вытребуется модуль gcs в верхней части облачной функции следующим образом:

const gcs = require('@google-cloud/storage')({keyFilename: 'service-account-credentials.json});

См. официальный пример Firebase, который подробно это показывает: https://github.com/firebase/functions-samples/blob/master/generate-thumbnail/functions/index.js

...