Funzione Firebase https onCall bloccata da cors

Nov 10 2020

Ho una sendMailfunzione cloud che desidero utilizzare per inviare e-mail da un modulo di contatto sul mio sito. Il sito è ospitato su Firebase con un dominio Google personalizzato. Il problema è che ottengo questo errore ogni volta che provo a richiamare la funzione dal sito ospitato.

Ecco cosa ho provato finora

  1. Ho provato a testare la funzione localmente dal browser e funziona perfettamente. Nessun errore di cors.
  2. Anche il test invocando la funzione dalla shell di Firebase funziona bene senza alcun errore di cors.

  1. Ho controllato la mia console Google Cloud e mi sono assicurato che tutti gli utenti possano richiamare la funzione.

4. Ho anche provato a utilizzare la libreria cors per eseguire il wrapping della funzione, ma neanche questo ha funzionato:

Ecco come chiamo la mia sendMailfunzione:

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

Ecco l'intera sendMailfunzione:

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

So che sono state fatte domande simili ma ho provato quasi tutto. Ricevo il problema SOLO quando lo richiamo dal mio sito ospitato da Firebase. Qualcuno, per favore, aiuta!

Risposte

2 Cleanbeans Nov 11 2020 at 06:36

onCall funziona in modo diverso rispetto a onRequest per quanto riguarda il cors, ad esempio è necessario assicurarsi di chiamarlo dalla stessa regione. Vedi questo post

Il problema cors può verificarsi se la tua funzione è in errore, vale la pena controllare nell'emmulatore e la risposta di invio della posta.