Reputation: 4783
I'm trying to use Firebase cloud functions to upload an image onto storage. When I run the function from a browser, I receive a '0' response, indicating that it failed. Afterwards I check the logs and it displays the error:
Upload bad! [Error: ENOENT: no such file or directory, stat 'https://i2.wp.com/lifemadesimplebakes.com/wp-content/uploads/2018/03/How-To-Make-Fruit-Salad-680x680.jpg'] {
The image url does exist though. So I'm wondering why it's not working? Here's my whole cloud function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
exports.uploadTest = functions.https.onRequest(async (request, response) => {
const url = 'https://i2.wp.com/lifemadesimplebakes.com/wp-content/uploads/2018/03/How-To-Make-Fruit-Salad-680x680.jpg';
admin.initializeApp();
const bucket = admin.storage().bucket('my-bucket.appspot.com');
bucket.upload(url, {
destination: "myFolder/myFile.png"
}).then(() => {
console.log("Upload good!");
response.send('1');
return true
}).catch(err => {
console.error("Upload bad!", err);
response.send('0');
});
})
Upvotes: 0
Views: 3056
Reputation: 4783
So after some more research, I got something to work.
On my frontend I'm encoding an image to base64 which I pass to my cloud function as a parameter imgData
. Then inside the function I retrieve it, make a Buffer
with the data, then upload it onto my bucket using File.save
.
Now it uploads, and if I download a url for it from the console and check it on a browser the image appears as expected.
My frontend needs to use REST so I'm unable to use Firebase's sdk at all, which probably would have made this much easier.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.uploadTest = functions.https.onRequest(async (request, response) => {
const imgData = request.body.imgData;
const bucket = admin.storage().bucket('my-bucket.appspot.com');
const file = bucket.file('myFolder/myFile.jpg');
var imgBuffer = new Buffer.from(imgData, 'base64')
await file.save(imgBuffer, {
contentType: 'image/jpeg'
}).catch(err => {
console.error("Upload bad!", err);
response.send('0');
});
response.send('1');
})
Here's some info that helped me along: https://groups.google.com/g/firebase-talk/c/aDJvYyNIJik?pli=1
Upvotes: 6
Reputation: 317808
Cloud Storage does not support directly uploading content from some URL. upload() doesn't take a URL. It takes a path to a local file.
As such, you will have to write code to download the contents of the URL locally, then upload that as an object to Cloud Storage. You could also stream the contents of the download into the storage using the SDK as well. See createWriteStream() for that. I suggest studying how node streams work in order to implement this effectively.
Upvotes: 1