Chima Precious
Chima Precious

Reputation: 273

Upload File to Firebase Storage using Admin SDK

According to the Docs, I have to pass the filename to the function in order to upload a file.

// 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',
  },
});

I am using Firebase Admin SDK (Nodejs) in my server side code and clients send file in form-data which i get as File Objects. How then do i upload this when the function accepts only filename leading to filepath.

I want to be able to do something like this


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

Upvotes: 25

Views: 24452

Answers (4)

Dustin Spengler
Dustin Spengler

Reputation: 7721

Here is an example of uploading an image to your Firebase Storage from an existing web url using 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=media&token=${token}`
   return finalUrl;
}

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

And here is and example of uploading an image that is saved to your local machine:

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=media&token=${token}`
   return finalUrl;
}

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

Upvotes: 2

Vinay Singh
Vinay Singh

Reputation: 59

I stumbled upon this question while uploading image from URL here's my solution by uploading 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',
           })

Upvotes: 5

Doug Stevenson
Doug Stevenson

Reputation: 317712

Since the Firebase Admin SDK just wraps the Cloud SDK, you can use the Cloud Storage node.js API documentation as a reference to see what it can do.

You don't have to provide a local file. You can also upload using node streams. There is a method File.createWriteStream() which gets you a WritableStream to work with. There is also File.save() which accepts multiple kinds of things, including a Buffer. There are examples of using each method here.

Upvotes: 16

Chukwuemeka Maduekwe
Chukwuemeka Maduekwe

Reputation: 8546

what you should do is use the built-in function

let's say you receive the file as imageDoc in the client side and

 const imageDoc = e.target.files[0]

in node, you can now get a URL path to the object as

 const imageDocUrl = URL.createObjectURL(imageDoc)

so your final code will be

    // 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',
     },
});

Upvotes: -1

Related Questions