【问题标题】:Get Firebase storage Object on a database-triggered cloud function在数据库触发的云函数上获取 Firebase 存储对象
【发布时间】:2017-08-08 10:15:51
【问题描述】:

我想在将记录添加到数据库时生成缩略图。 在 Firebase 网站上,他们有一些示例,但它们都是基于存储触发器而不是数据库触发器:

图像数据库对象:

image: {
  name: abc123,
  raw: download url abc123 
}

-

firebase thumb 生成器示例(存储触发):

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

  const fileBucket = object.bucket; // The Storage bucket that contains the file.
  const filePath = object.name; // File path in the bucket.
  const contentType = object.contentType; // File content type.
  const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions).
  const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.

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

  // Get the file name.
  const fileName = path.basename(filePath);
  // Exit if the image is already a thumbnail.
  if (fileName.startsWith('thumb_')) {
    console.log('Already a Thumbnail.');
    return;
  }

  // Exit if this is a move or deletion event.
  if (resourceState === 'not_exists') {
    console.log('This is a deletion event.');
    return;
  }

  // Exit if file exists but is not new and is only being triggered
  // because of a metadata change.
  if (resourceState === 'exists' && metageneration > 1) {
    console.log('This is a metadata change event.');
    return;
  }

  // Download file from bucket.
  const bucket = gcs.bucket(fileBucket);

  const metadata = {
    contentType: contentType
  };
  // We add a 'thumb_' prefix to thumbnails file name. That's where we'll upload the thumbnail.
  const thumbFileName = `thumb_${fileName}`;
  const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
  // Create write stream for uploading thumbnail
  const thumbnailUploadStream = bucket.file(thumbFilePath).createWriteStream({metadata});

  // Create Sharp pipeline for resizing the image and use pipe to read from bucket read stream
  const pipeline = sharp();
  pipeline
    .resize(THUMB_MAX_WIDTH, THUMB_MAX_HEIGHT)
    .max()
    .pipe(thumbnailUploadStream);

  bucket.file(filePath).createReadStream().pipe(pipeline);

  const streamAsPromise = new Promise((resolve, reject) =>
    thumbnailUploadStream.on('finish', resolve).on('error', reject));
  return streamAsPromise.then(() => {
    console.log('Thumbnail created successfully');
  });
});

-

我希望它如何工作(数据库触发):

数据库触发事件没有存储对象。如何访问存储对象? 成功创建缩略图后,我想将缩略图的 donwloadUrl 添加到数据库中

exports.generateThumbnail = functions.database.ref('/data/{dataID}/childData/{childDataID}/image/name').onCreate(event => {

      const object = event.data; // This Storage object does not work when using a database trigger so how do I access the same storage object, I have the image name?

      //thumb generator code...

      return streamAsPromise.then(() => {
        console.log('Thumbnail created successfully');
        //add thumb image download url back to the database
      });
    });

-

image: {
  name: abc123,
  raw: download url abc123
  thumb: download url thumb_abc123  //added after thumb is created
}

【问题讨论】:

    标签: firebase firebase-storage google-cloud-functions


    【解决方案1】:

    这就是我让它工作的方式。

    为您的项目添加云存储。
    如果您想像我一样检索图像签名的 url,请将 projectId 和 keyFilename 添加到您的云存储参考

    const gcs = require('@google-cloud/storage')({
      projectId: 'name-1234', 
      keyFilename: './keyfile.json'
    });
    

    生成缩略图函数

    exports.generateThumbnail = functions.database.ref('/data/${dataID}/childData/${childDataID/image/name').onCreate(image => {
    
      const dataID = image.params.dataID
      const childDataID = image.params.childDataID 
      const fileName = image.data.val()
    
      //get your project storage bucket id
      const storageBucket = functions.config().firebase.storageBucket
      //path to image
      const imagePath = `${dataID}/${childDataID}`
      //open bucket
      const bucket = gcs.bucket(storageBucket)
      //location of the image in the bucket
      const object = bucket.file(imagePath)
    
      const fileBucket = object.bucket; // The Storage bucket that contains the file.
      const filePath = object.name; // File path in the bucket.
    
      const metadata = {
        contentType: 'image/jpeg'
      };
    
      // We add a 'thumb_' prefix to thumbnails file name. That's where we'll upload the thumbnail.
      const thumbFileName = `thumb_${fileName}`;
      const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
      // Create write stream for uploading thumbnail
      const thumbnailUploadStream = bucket.file(thumbFilePath).createWriteStream({metadata});
    
      // Create Sharp pipeline for resizing the image and use pipe to read from bucket read stream
      const pipeline = sharp();
      pipeline
        .resize(400, 400)
        .max()
        .pipe(thumbnailUploadStream);
    
    
      bucket.file(filePath).createReadStream().pipe(pipeline);
    
      const streamAsPromise = new Promise((resolve, reject) =>
        thumbnailUploadStream.on('finish', resolve).on('error', reject));
    
      return streamAsPromise.then(() => {
        console.log('Thumbnail created successfully');
    
        var today = new Date();
        var dd = today.getDate();
        var mm = today.getMonth() + 1; //January is 0!
        const yyyy = today.getFullYear() + 5; // add a few years
    
        if (dd < 10) {
          dd = '0' + dd
        } 
    
        if (mm < 10) {
          mm = '0' + mm
        } 
    
        today = mm + '-' + dd + '-' + yyyy;
    
        bucket.file(filePath).getSignedUrl({
          action: 'read',
          expires: today
        }, function(err, url) {
          if (err) {
            console.error(err);
            return;
          }
          //add thumb image url to message (in database)
          return admin.database().ref(`/${dataID}/childData/${childDataID}`).child('image').update({ 
            thumb: url
          })
        });
      });
    })
    

    【讨论】:

    • 对不起,我在这里遗漏了一些东西......像 ${dataID} 这样的变量是如何传递给触发器的?
    • @andehlu 上传原始图像时,它将被上传到特定路径,例如/data/12345/childData/54321/image/name.上传此图像时,将触发“generateThumbnail”功能并读取图像路径。所以在这个例子中 ${dataID} = 12345。你可以通过 'generateThumbnail' 函数变量 'image' (.onCreate(image =>...) 访问 ${dataID} 所以 image.params.dataID = 12345 所以 'const dataID' = 12345。希望这回答了你的问题。
    猜你喜欢
    • 2018-02-21
    • 1970-01-01
    • 2019-12-18
    • 2021-06-07
    • 2020-06-21
    • 2018-09-14
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    相关资源
    最近更新 更多