1

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.

Prashin Jeevaganth
  • 1,223
  • 1
  • 18
  • 42
  • Does this answer your question? https://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud-functions-for-firebase?rq=1 – Happy-Monad Jun 05 '20 at 07:53

0 Answers0