Función de Firebase https onCall bloqueada por cors

Nov 10 2020

Tengo una sendMailfunción en la nube que quiero usar para enviar correos electrónicos desde un formulario de contacto en mi sitio. El sitio está alojado en Firebase con un dominio de Google personalizado. El problema es que obtengo este error cada vez que intento invocar la función desde el sitio alojado.

Esto es lo que he probado hasta ahora

  1. He intentado probar la función localmente desde el navegador y funciona bien. Sin error de cors.
  2. La prueba al invocar la función desde el shell de base de fuego también funciona bien sin ningún error de cors.

  1. Revisé mi consola de Google Cloud y me aseguré de que todos los usuarios puedan invocar la función.

4. También intenté usar la biblioteca cors para ajustar la función, pero tampoco funcionó:

Así es como llamo a mi sendMailfunción:

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);
      });
  };

Aquí está la sendMailfunción completa :

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);
      }
    });
  });

Sé que se han hecho preguntas similares, pero realmente he intentado casi todo. SOLO obtengo el problema de cors cuando lo invoco desde mi sitio alojado en firebase. ¡Alguien, por favor ayuda!

Respuestas

2 Cleanbeans Nov 11 2020 at 06:36

Las funciones onCall se comportan de manera diferente a onRequest con respecto a los cors, por ejemplo, debe asegurarse de llamarlo desde la misma región. Ver esta publicación

El problema de cors puede ocurrir si su función es errónea, vale la pena consultar el emmulator y su respuesta de envío de correo.