代码之家  ›  专栏  ›  技术社区  ›  Michael Giovanni Pumo

如何在Firebase云功能中获取上传的图像链接[[副本]

  •  0
  • Michael Giovanni Pumo  · 技术社区  · 6 年前

    我有一个云函数,可以为上传的每个图像生成一组大小调整后的图像。这是由 onFinalize()

    用于调整上载图像大小的云函数:

    export const onImageUpload = functions
      .runWith({
        timeoutSeconds: 120,
        memory: '1GB'
      })
      .storage
      .object()
      .onFinalize(async object => {
        const bucket = admin.storage().bucket(object.bucket)
        const filePath = object.name
        const fileName = filePath.split('/').pop()
        const bucketDir = dirname(filePath)
        const workingDir = join(tmpdir(), 'resizes')
        const tmpFilePath = join(workingDir, fileName)
    
        if (fileName.includes('resize@') || !object.contentType.includes('image')) {
          return false
        }
    
        await fs.ensureDir(workingDir)
    
        await bucket.file(filePath).download({
          destination: tmpFilePath
        })
    
        const sizes = [
          500,
          1000
        ]
    
        const uploadPromises = sizes.map(async size => {
          const resizeName = `resize@${size}_${fileName}`
          const resizePath = join(workingDir, resizeName)
    
          await sharp(tmpFilePath)
            .resize(size, null)
            .toFile(resizePath)
    
          return bucket.upload(resizePath, {
            destination: join(bucketDir, resizeName)
          })
        })
    
        // I need to now update my Firestore database with the public URL.
        // ...but how do I get that here?
    
        await Promise.all(uploadPromises)
        return fs.remove(workingDir)
      })
    

    getDownloadURL() ,但我不确定如何从新生成的图像的云函数中执行此操作。

    在我看来,这无论如何都需要在后端发生,因为我的前端无法知道图像何时被处理。

    const storageRef = firebase.storage().ref()
    const url = await storageRef.child(`images/${image.name}`).getDownloadURL()
    

    答复(附带警告):

    1. 似乎的“expires”参数 getSignedUrl() 根据TypeScript,必须是一个数字。所以,为了让它工作,我必须传递一个未来的日期,用历元(毫秒)表示,比如 3589660800000 .

    2. 我需要把证书传给你 admin.initializeApp() 为了使用这种方法。您需要在Firebase管理员中生成服务帐户密钥。请看这里: https://firebase.google.com/docs/admin/setup?authuser=1

    1 回复  |  直到 6 年前
        1
  •  4
  •   Sergio    6 年前

    我相信bucket upload返回的承诺包含对该文件的引用,然后您可以使用该文件获取签名URL。

    类似(未经测试):

    const data = await bucket.upload(resizePath, { destination: join(bucketDir, resizeName) });
    const file = data[0];
    const signedUrlData = await file.getSignedUrl({ action: 'read', expires: '03-17-2025'});
    const url = signedUrlData[0];