【问题标题】:Update Firebase database on Storage change using Firebase Functions使用 Firebase 函数更新存储更改的 Firebase 数据库
【发布时间】:2017-10-20 13:04:56
【问题描述】:

我正在尝试在我的 Android 应用中实现个人资料图片功能。所以我使用了来自 firebase 的 Generate Thumbnail 样本。因此,每当我上传全尺寸图像时,它都会为我生成缩略图。但是一旦生成缩略图,我想在我的实时数据库中更新缩略图的 URL。

const functions = require('firebase-functions');
const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
const spawn = require('child-process-promise').spawn;
const LOCAL_TMP_FOLDER = '/tmp/';

// Max height and width of the thumbnail in pixels.
const THUMB_MAX_HEIGHT = 100;
const THUMB_MAX_WIDTH = 100;
// Thumbnail prefix added to file names.
const THUMB_PREFIX = 'thumb_';

/**
 * When an image is uploaded in the Storage bucket We generate a thumbnail automatically using
 * ImageMagick.
 */
exports.generateThumbnail = functions.storage.object().onChange(event => {
  const filePath = event.data.name;
  const filePathSplit = filePath.split('/');
  const fileName = filePathSplit.pop();
  const fileDir = filePathSplit.join('/') + (filePathSplit.length > 0 ? '/' : '');
  const thumbFilePath = `${fileDir}${THUMB_PREFIX}${fileName}`;
  const tempLocalDir = `${LOCAL_TMP_FOLDER}${fileDir}`;
  const tempLocalFile = `${tempLocalDir}${fileName}`;
  const tempLocalThumbFile = `${LOCAL_TMP_FOLDER}${thumbFilePath}`;

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

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

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

  // Create the temp directory where the storage file will be downloaded.
  return mkdirp(tempLocalDir).then(() => {
    // Download file from bucket.
    const bucket = gcs.bucket(event.data.bucket);
    return bucket.file(filePath).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]).then(() => {
        console.log('Thumbnail created at', tempLocalThumbFile);
        // Uploading the Thumbnail.
        return bucket.upload(tempLocalThumbFile, {
          destination: thumbFilePath
        }).then(() => {
          console.log('Thumbnail uploaded to Storage at', thumbFilePath);
          // Don't know what to write here.
        });
      });
    });
  });
});

一旦此代码的最终承诺完成,我想从生成的个人资料图片中获取可下载的 URL,地址为 /users/{userId}/profilePic

【问题讨论】:

    标签: node.js firebase firebase-realtime-database firebase-storage google-cloud-functions


    【解决方案1】:

    您需要添加一些东西才能在此处实现您想要的。首先,您需要使用 firebase-admin 并初始化应用程序。

    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);
    

    这应该在您需要其他组件之后在文件顶部完成。

    一旦你知道了,你可以在最终的承诺中添加一些代码,用新的引用更新数据库。

    .then(() => {
          console.log('Thumbnail uploaded to Storage at', thumbFilePath);
           //userID here would be the userID that you want to update. I couldn't see a reference to it in the code you provided.
           var databaseRef = admin.database().ref('users').child(userID).child("profilePic");
           databaseRef.transaction(function(oldValue) {
               return bucket.file(thumbFilePath).getDownloadURL().then(funct‌​ion(url) {
                    return url;
               }
    
           });
    });
    

    您可以在此处阅读有关交易以更新参考的信息。我只包含了强制事务更新 参数而不是您可能需要的可选参数。 https://firebase.google.com/docs/reference/admin/node/admin.database.Reference#transaction

    【讨论】:

    • 感谢您的回答。但是请您帮我获取可下载的 URL 而不是 thumbFilePath。由于我想存储在 Db 中并检索它以存储在我的 UI 中,因此我需要可下载的 URl。
    • 有一个专门用于返回下载参考的函数。 databaseRef.child(thumbFilePath).getDownloadURL().then(function(url) {我已经编辑了我的答案,显示了它的样子
    • getDownloadURL() 应该从 databaseRef 或 storageRef 调用吗?
    • 这不起作用,因为 getDownloadURL 不是来自 databaseRef。
    • 对不起,你就在那儿,应该从 storageRef 调用,我已经编辑了可能看起来像什么的答案,但我之前没有使用过它,所以它可能需要调整或两个。
    猜你喜欢
    • 2019-02-18
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多