Загрузить файл в хранилище Firebase с помощью Admin SDK

#node.js #firebase #express #google-cloud-storage #firebase-admin

#node.js #firebase #экспресс #google-облачное хранилище #firebase-администратор

Вопрос:

Согласно документам, я должен передать имя файла функции, чтобы загрузить файл.

 // Uploads a local file to the bucket
await storage.bucket(bucketName).upload(filename, {
  // Support for HTTP requests made with `Accept-Encoding: gzip`
  gzip: true,
  metadata: {
    // Enable long-lived HTTP caching headers
    // Use only if the contents of the file will never change
    // (If the contents will change, use cacheControl: 'no-cache')
    cacheControl: 'public, max-age=31536000',
  },
});
  

Я использую Firebase Admin SDK (Nodejs) в своем серверном коде, и клиенты отправляют файл в виде данных, которые я получаю в виде файловых объектов. Как тогда мне загрузить это, если функция принимает только имя файла, ведущее к filepath.

Я хочу иметь возможность делать что-то вроде этого

 
app.use(req: Request, res: Response) {
 const file = req.file;
// upload file to firebase storage using admin sdk
}

  

Ответ №1:

Поскольку Firebase Admin SDK просто оборачивает Cloud SDK, вы можете использовать облачное хранилище node.js Документация API в качестве ссылки, чтобы увидеть, что он может сделать.

Вам не нужно предоставлять локальный файл. Вы также можете загружать с помощью node streams. Существует метод File.createWriteStream(), который предоставляет вам записываемый поток для работы. Существует также File.save(), который принимает различные типы данных, включая буфер. Здесь приведены примеры использования каждого метода.

Комментарии:

1. URL не работает

2. исправлено указывать на https://googleapis.dev/nodejs/storage/latest /

3. Вы также могли бы обратиться к https://github.com/googleapis/nodejs-storage/blob/main/samples/streamFileUpload.js для потоковой загрузки файла

Ответ №2:

Я наткнулся на этот вопрос при загрузке изображения с URL, вот мое решение путем загрузки buffer.

 const fileContent = await fetch(url)
const buffer = await fileContent.arrayBuffer()
const bf = Buffer.from(buffer)
const id = uuid()
const bucket = storage.bucket()

const file = bucket.file('filePath'   id   '.png')

const up = await file.save(bf, {
                 contentType: 'image/png',
                 cacheControl: 'public, max-age=31536000',
           })

  

Ответ №3:

Вот пример загрузки изображения на ваш Firebase Storage сайт с существующего веб-URL с помощью Firebase Admin Node.js:

 var firebase = require("firebase-admin");
const uuid = require('uuid-v4');
const fetch = require('node-fetch');
const storageUrl = "https://firebasestorage.googleapis.com/v0/b/your-app-name.appspot.com/o"

const uploadImageFromUrl = async (remoteimageurl, filename) => {
   let res = await fetch(remoteimageurl)
   const buffer = await res.arrayBuffer()
   const bf = Buffer.from(buffer)
   const token =  uuid();
   const metadata = {
      metadata: {
         firebaseStorageDownloadTokens: token,
      },
      contentType: 'image/png',
      cacheControl: 'public, max-age=31536000',
   };
   await firebase.storage().bucket().file(`${filename}`).save(bf, {
      metadata: metadata,
   });
   const finalUrl = `${storageUrl}/${filename}?alt=mediaamp;token=${token}`
   return finalUrl;
}

const catImageUrl = "https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png"
uploadImageFromUrl(catImageUrl, "test.jpg"); //example
  

А вот и пример загрузки изображения, сохраненного на вашем локальном компьютере:

 var firebase = require("firebase-admin");
const uuid = require('uuid-v4');
const storageUrl = "https://firebasestorage.googleapis.com/v0/b/your-app-name.appspot.com/o"

const uploadImageFromLocal = async (localUrl, filename) => {
   const token =  uuid();
   const metadata = {
      destination: `foo/sub/${filename}`,
      metadata: {
         firebaseStorageDownloadTokens: token,
      },
      contentType: 'image/png',
      cacheControl: 'public, max-age=31536000',
   };
   await firebase.storage().bucket().upload(`${localUrl}`, metadata);
   let finalUrl = `${storageUrl}/foo/sub/${filename}?alt=mediaamp;token=${token}`
   return finalUrl;
}

const localImageUrl = "foo/sub/cat.jpg";
uploadImageFromLocal(localImageUrl, "test.jpg"); //example
  

Ответ №4:

что вам следует сделать, так это использовать встроенную функцию

допустим, вы получаете файл как imageDoc на стороне клиента и

  const imageDoc = e.target.files[0]
  

в node теперь вы можете получить URL-путь к объекту в виде

  const imageDocUrl = URL.createObjectURL(imageDoc)
  

итак, ваш окончательный код будет

     // Uploads a local file to the bucket
    await storage.bucket(bucketName).upload(imageDocUrl, {
        // Support for HTTP requests made with "Accept-Encoding: gzip"
        gzip: true,
         metadata: {
           // Enable long-lived HTTP caching headers
           // Use only if the contents of the file will never change
           // (If the contents will change, use cacheControl: 'no-cache')
           cacheControl: 'public, max-age=31536000',
     },
});
  

Комментарии:

1. я пытался это сделать, но получаю сообщение об ошибке Error: ENOENT: no such file or directory, stat 'E:Serverblob:http:localhost:300034544810-4aa6-4070-adf8-15c636b92c29' есть ли другой способ?

2. @Billjesh вы можете попробовать сначала сохранить изображение во временной папке на вашем сервере, затем использовать описанный выше метод для загрузки изображения, но вам придется заменить imageDocUrl путь к изображению, которое вы только что сохранили локально