Reputation: 273
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
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
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
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
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