I am trying to implement an upload profile image feature for a users
collection. I implement an async function as such
exports.async_upload_image = async function(req, res) {
const path = require("path");
const os = require("os");
const fs = require("fs");
const { Storage } = require('@google-cloud/storage');// end up no need
let gcs = new Storage({
projectId: config.projectId
});
try {
const newFilePath = req.filepath;
const baseName = newFilePath.split("/").pop();
if (req.mimetype !== "image/jpeg" && req.mimetype !== "image/png") {
console.log("Wrong file type submitted");
return null;
}
// my.image.png => ['my', 'image', 'png']
const image_extension = newFilePath.split(".")[newFilePath.split(".").length - 1];
// 32756238461724837.png
let generated_token = uuid();
let image_filename = `${generated_token}.${image_extension}`;
const processed_path = path.join(os.tmpdir(), image_filename);
//creates a copy of image file inside the temporary path
const input_file = fs.createReadStream(newFilePath);
const output_file = fs.createWriteStream(processed_path);
input_file.pipe(output_file);
//upload to the firebase storage from the temporary path
await gcs.bucket(config.storageBucket).upload(processed_path, {
gzip: true,
metadata: {
cacheControl: "no-cache",
contentType: req.mimetype,
firebaseStorageDownloadTokens: generated_token
}
})
const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${image_filename}?alt=media&token=${generated_token}`;
// await gcs.bucket(config.storageBucket).upload(newFilePath, {
// gzip: true,
// metadata: {
// cacheControl: "no-cache",
// contentType: req.mimetype,
// firebaseStorageDownloadTokens: generated_token
// }
// })
// const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${baseName}?alt=media&token=${generated_token}`;
await db.collection(USERS_PUBLIC_COLLECTION).doc(req.user_id).update({
profile_image:
{
uid: generated_token,
url: imageUrl
}
})
console.log(`Update profile to uploaded image ${generated_token} successfully`);
return success_response();
} catch (error) {
console.log(error);
}
}
And wrote this at the bottom and ran with node file.js
in the same file.
const req = {
filepath: some_file_path,
mimetype: "image/png",
user_id: "valid_user_id"
}
exports.async_upload_image(req);
The picture does get uploaded to storage as well as updating my document in the Firestore, but it was intended that accessing URL under the url
in the profile_image
map will allow me to see the picture. This works for the unprocessed picture, whose code segment is commented out, but not for the changed image. I also noted that the file size is incredibly small, around 20B. Can someone tell me why and what might be a better way to upload images with firebase? Feel free to clarify if more info is required to solve the problem.