reactjsfirebasegoogle-cloud-functionscors

Firebase https onCall function blocked by cors


I have a sendMail cloud function that I want to use to send emails from a contact form on my site. The site is hosted on Firebase with a custom Google domain. The issue is that I get this error whenever I try to invoke the function from the hosted site.

enter image description here

Here's what I have tried so far

  1. I have tried testing the function locally from the browser and it works just fine. No cors error.
  2. Testing by invoking the function from the firebase shell also works just fine without any cors error.

enter image description here

  1. I have checked my Google Cloud console and made sure all users can invoke the function. enter image description here

4. I have also tried using the cors library to wrap the function but that hasn't worked either:

Here is how I am calling my sendMail function:

handleSubmit = (e) => {
    e.preventDefault();
    const sendMail = firebase.app().functions('us-central1').httpsCallable("sendMail");
    
    sendMail({ details: this.state })
      .then((res) => {
        this.setState({
          loading: true,
        });
        this.notify("success");
      })
      .catch((error) => {
        this.notify(error);
      });
  };

Here is the entire sendMail function:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const cors = require("cors")({ origin: true });
const nodemailer = require("nodemailer");

admin.initializeApp();

// Use gmail to set up transporter
let transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: functions.config().mail.user,
    pass: functions.config().mail.pass
  },
});

exports.sendMail = functions
  .region("us-central1")
  .https.onCall((data, context) => {
    const info = data.details;
    const mailOptions = {
      from: `${info.name} <${info.email}>`,
      to: functions.config().mail.dest,
      subject: info.subject,
      html: `<p style="font-size: 16px;">${info.name}, ${info.email}</p>
                    <p
                    style="
                        font-size: 1rem;
                        background: #FFECB3;
                        padding: 10px;
                        border-radius: 10px;">${info.message}</p>
                `, // email content in HTML
    };

    // returning results
    return transporter.sendMail(mailOptions, (err, info) => {
      if (err) {
        console.log("failed", err);
      }
    });
  });

I know similar questions have been asked but I have really tried almost everything. I ONLY get the cors issue when invoking it from my firebase hosted site. Someone, please help!


Solution

  • onCall functions behaviour differently than onRequest with regards to the cors, for example you need to ensure you're calling it from the same region. See this post

    The cors issue can occur if your function is erroring, worth checking in the emulator & your send mail response.