Search code examples
firebasecloudstoragenodemailer

Firebase Cloud Storage trigger on Specific File Upload


I'm trying to build the functionality that will automatically trigger an email through nodemailer when a specific file is uploaded to Firebase Storage. For flow - a user completes a form, the data is aggregated and a PDF is automatically generated, the PDF is then added to Cloud Storage.

The Storage path is "UserFiles/{uID}/"(in here lives the user's file)". When a specific file is finalized in Storage (called "Resume.pdf"), I'd like to send all of the files in that uID folder. Is this possible with cloud functions? I've built functionality to manually trigger this if a user clicks a button, but I'd like the email to automatically be sent when the upload is complete.

Here is the manual send (works fine):

  const getDocumentURLs = () => {
firebase
  .storage()
  .ref("Tenant Resumes/" + firebase.auth().currentUser.uid)
  .listAll()
  .then((res) => {
    res.items.forEach((result) => {
      result.getDownloadURL().then((docURL) => {
        setDocumentData((newURLs) => [...newURLs, docURL]);
        console.log(docURL);
      });
    });
  });
  };

  const sendMailFunction = async () => {
console.log(documentData);
const sendMailOverHTTP = firebase
  .functions()
  .httpsCallable("sendMailOverHTTP");
sendMailOverHTTP({
  replyTo: userInfo.email,
  name: userInfo.firstName + " " + userInfo.lastName,
  documentOne: documentData[0] ? documentData[0] : "",
  documentTwo: documentData[1] ? documentData[1] : "",
  documentThree: documentData[2] ? documentData[2] : "",
  documentFour: documentData[3] ? documentData[3] : "",
  documentFive: documentData[4] ? documentData[4] : "",
  documentSix: documentData[5] ? documentData[5] : "",
})
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.log(error);
  });

};

How would I use this same methodology with a cloud function?

I'm trying:

    exports.sendAutomatedResume = functions.storage.bucket("Resumes/{uID}/Resume.pdf")
  .object()
  .onFinalize(async (object) => {

But it doesn't seem to be working. Any thoughts?


Solution

  • Cloud Storage triggers aren't able to pre-filter based on the path of the uploaded file, but you can create a generic onFinalize function that returns early if the path doesn't match. For example:

    exports.sendAutomatedResume = functions.storage.bucket().object()
      .onFinalize(async (object) => {
        const [folder, uid, filename, ...rest] = object.name.split("/");
        if (folder !== "Resumes" || filename !== "Resume.pdf" || rest.length > 0) {
          // doesn't match, so return early
          return;
        }
    
        // does match, do stuff here
      });