使用firebase-admin将图像上传到Firebase存储

时间:2020-09-23 09:03:50

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

使用firebase-admin包将图像上传到Firebase项目时,我总是很难受。

当我使用我的应用程序的admin部分(使用常规的firebase JS软件包)以admin用户身份上传图片时,会看到以下内容。

这是我使用的代码:

const metadata = {
  cacheControl: "public,max-age=31536000,must-revalidate"
  // contentType: "image/jpeg" // THIS IS AUTO INFERRED BY FIREBASE
};


const storageRef = firebase.storage().ref(`${directory}/${fileName}`);
const uploadTask = storageRef.put(file,metadata);

uploadTask.on("state_changed",
  function progress() {...},
  function error() {...},
  function complete() {...}
);

这就是我在Firebase存储控制台上得到的:带有链接和下载令牌的漂亮预览。即使未显示cacheControl元数据,也已经设置好了,因为当我在浏览器中访问图像的URL时,它是可见的。

enter image description here

现在,我正在编写一个admin脚本,以将本地计算机上的某些图像上传到Firebase存储。

这是代码:

async function uploadImage() {

  admin.storage().bucket().upload(
    `./temp/${imageLocation}`,       // THIS IS MY LOCAL PATH
    { 
      destination: imageLocation,    // THIS IS THE PATH FOR THE STORAGE
    }
  );
  console.log(`Uploaded: ${imageLocation}`);
}

一切正常,文件确实已上传,但这是我在Firebase存储控制台上得到的:

enter image description here

问题

如何使用firebase-admin来获得与在浏览器上使用firebase JS包上传图像时相同的一致结果?

我可以在NodeJs管理脚本中使用常规的firebase软件包吗?我认为在发出admin请求之前,我必须先以firebase.storage().ref().put()用户身份进行身份验证,因为所有存储路径都受allow write: if request.auth.token.admin == true;保护。

2 个答案:

答案 0 :(得分:2)

您需要添加uuidv4软件包:

const { uuid } = require('uuidv4')

bucket.upload('cat.png', {
    destination: 'cat.png',
    metadata: {
        metadata: {
            firebaseStorageDownloadTokens: uuid(),
        }
    },
})

答案 1 :(得分:0)

这是我的处理方式:

当您使用firebase JS SDK将内容上传到存储时,它会自动添加一些元数据。

AFAIK,它添加了两个元数据:

const metadataObject = {
  contentDisposition: `inline; filename*=utf-8''${fileName}`  // THIS IS "REGULAR METADATA"
  metadata: {
    firebaseStorageDownloadTokens: downloadToken  // THIS IS "CUSTOM METADATA"
  }
}

downloadToken只是用uuid()生成的唯一密钥。正如我们从Cloud Console(而不是firebase控制台的以下代码片段中看到的那样,因为您无法从那里看到元数据)。

enter image description here

因此,在使用firebase-admin包上传图像时,您需要模仿这种行为。

这是您的操作方式:

import * as admin from "firebase-admin";
import { v4 as uuid } from "uuid";

// INITIALIZE THE ADMIN WITH YOUR SERVICE ACCOUNT CREDENTIALS

admin.initializeApp({...});

/* ########################### */ 
/* #### GENERATE METADATA #### */
/* ########################### */ 

function generateMetadataObject(fileName: string) {
  const downloadToken = uuid();
  const metadataObject = {
    contentType: `image/jpeg`,  // contentType IS OPTIONAL CAUSE IT WILL BE AUTO-INFERRED
    cacheControl: `public,max-age=31536000,must-revalidate`,  // YOU CAN ALSO USE IT TO ADD OTHER METADATA LIKE cacheControl
    contentDisposition: `inline; filename*=utf-8''${fileName}`,
    metadata: {
      firebaseStorageDownloadTokens: downloadToken
    }
  };
  return metadataObject;
}

/* ##################################################### */
/* #### UPLOAD LOCAL IMAGE TO STORAGE WITH METADATA #### */
/* ##################################################### */

async function uploadImage() {

  const imageLocation = "/some/local_folder/someImage.jpg";
  const fileName = "someImage.jpg";

  await admin.storage().bucket().upload(
    imageLocation,   // THIS IS THE LOCAL PATH OF THE FILE
    {
      destination: "some/bucket_folder/someImage.jpg",  // THIS IS THE BUCKET PATH
      metadata: generateMetadataObject(fileName)        // ADD METADATA OBJECT
    }
  );
  console.log("File with metadata was uploaded to bucket..."); 
}

这样做,您将获得与使用常规firebase JS SDK包上传文件相同的行为并在Firebase控制台上预览。