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

Uploading images to Firebase Storage using firebase-admin

当我使用 firebase-admin 包将图像上传到我的 Firebase 项目时,我总是遇到困难。

这是我以管理员用户身份上传图片时得到的结果,使用我的应用程序的管理部分,该部分使用常规 firebase JS 包。

这是我使用的代码:

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 时它是可见的。

现在我正在编写一个 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 存储控制台上得到的:

问题

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

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

的保护

您需要添加uuidv4包:

const { uuid } = require('uuidv4')

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

我是这样处理的:

当您使用 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() 生成的唯一键。正如我们从云控制台(不是 firebase 控制台,因为您无法从那里看到元数据)的下面代码片段中看到的那样。

因此,当您使用 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 控制台上获得相同的行为和预览,就像您使用常规 firebase JS SDK 包上传文件一样。