Firebase存储从Node.js上传图像文件

kupeojn6  于 2023-01-30  发布在  Node.js
关注(0)|答案(5)|浏览(119)

请帮帮忙
我从客户端接收图像并将其保存在服务器的文件系统中,然后处理该图像,之后需要将其上传到firebase存储
我尝试在异步函数中将图像文件从Node.js上传到firebase存储

const path = process.cwd() + '/my_image.jpg';
const file = readFileSync(path);
await firebase.storage().ref().child('my_image.jpg').put(file);
...

但是我有错误
第一个参数必须是字符串类型或Buffer示例。已收到Uint8Array示例
好吧,我试试二进制格式

const path = process.cwd() + '/my_image.jpg';
const file = readFileSync(path, { encoding: 'base64' });
await firebase.storage().ref().child('my_image.jpg').putString(file, 'base64');
...

我得到错误
火源储存:字符串与格式"base64"不匹配:找到无效字符"
我已经试过很多方法了,但是都不管用!我做错了什么?

e1xvtsh3

e1xvtsh31#

您可以在这里使用此代码

var admin = require("firebase-admin");
const uuid = require('uuid-v4');

// CHANGE: The path to your service account
var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    storageBucket: "<BUCKET_NAME>.appspot.com"
});

var bucket = admin.storage().bucket();

var filename = "path/to/image.png"

async function uploadFile() {

  const metadata = {
    metadata: {
      // This line is very important. It's to create a download token.
      firebaseStorageDownloadTokens: uuid()
    },
    contentType: 'image/png',
    cacheControl: 'public, max-age=31536000',
  };

  // Uploads a local file to the bucket
  await bucket.upload(filename, {
    // Support for HTTP requests made with `Accept-Encoding: gzip`
    gzip: true,
    metadata: metadata,
  });

console.log(`${filename} uploaded.`);

}

uploadFile().catch(console.error);

要成功运行此代码,您需要:

  • 将Firebase Admin SDK添加到服务器
  • 安装uuid-v4
  • "path/to/serviceAccountKey.json"替换为您自己的服务帐户的路径。以下是获取您的服务帐户的指南。
  • <BUCKET_NAME>替换为默认存储桶的名称。您可以在Firebase Console的“存储”部分找到此名称。存储桶名称不得包含gs://或任何其他协议前缀。例如,如果Firebase控制台中显示的存储桶URL为gs://bucket-name.appspot.com,则将字符串bucket-name.appspot.com传递给Admin SDK。
  • "path/to/image.png"替换为您自己的映像的路径。
  • 如果需要,请相应地调整metadata中的contentType

只是想让你知道,每当你使用Firebase Console上传一个映像,一个 * 访问令牌 * 将自动生成。但是,如果你使用任何Admin SDK或gsutil上传一个映像,你将需要自己手动生成这个访问令牌。这就是为什么uuid部分是非常重要的

Firebase支持说这个问题正在修复中,但我认为任何有这个问题的人都应该这样做,而不是等待Firebase来修复这个问题。

lmvvr0a8

lmvvr0a82#

对于节点js,有一个名为'@google-cloud/storage的库

const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

const bucket = storage.bucket("my-bucket.appspot.com");
await bucket.upload(
            '/my_image_path.jpg', 
            {
                destination: 'my_uploaded_image.jpg',
                metadata: {
                    cacheControl: "public, max-age=315360000", 
                    contentType: "image/jpeg"
             }
        });

https://www.npmjs.com/package/@google-cloud/storage
您可能需要使用服务帐户密钥验证您的nodejs客户端。

ehxuflar

ehxuflar3#

也许几个月前上传Uint8Array到Storage是不可能的,但现在你可以做到了,唯一的问题是你必须在一个元数据对象中添加内容类型,方法是:

const file = new Uint8Array(...)
const metadata = { contentType: 'image/jpeg; charset=utf-8' }
const storageRef = firebase.storage().ref().child('path/to/image.jpg')

await storageRef.put(file, metadata).then((snapshot) => {
  console.log('Uploaded an array!', snapshot)
})
b4lqfgs4

b4lqfgs44#

可能您的节点版本不支持带有{ encoding: 'base64' }选项的readFileSync函数。
尝试原始方式转换缓冲区为字符串:

const file = readFileSync(path).toString('base64');
// now file is a base64 string
await firebase.storage().ref().child('my_image.jpg').putString(file, 'base64');
tp5buhyn

tp5buhyn5#

使用Firebase-admin与服务帐户使您能够上传文件在Firebase

const admin= require('firebase-admin')

var serviceAccount = require("/pathTOServiceAccount.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

var bucket=admin.storage().bucket('your/firebaseStorage/folderPath')

bucket.upload('pathOfThe/FileIn/Backend',{

  destination: 'path/in/firebase/storage',
  metadata: {
      cacheControl: "public, max-age=315360000", 
      contentType: "image/jpeg"
}
}
)

相关问题