首页 > 解决方案 > unable to get data sent from function call to firebase cloud functions

问题描述

I have a firebase function called sendMail that is used to send emails. I am trying to pass the email address of the receiver and another parameter to the function. In my vue app I call the function as follows:

sendEmail(){
            console.log(this.email)
            let sendMail = firebase.functions().httpsCallable('sendMail');
            sendMail(
                {
                    "email": this.email,
                    "superu": this.superu
                }
            ).then(
                result => {
                    console.log(result)
                }
            )
        }

And my function index.js looks like:

const functions = require('firebase-functions');
const admin = require("firebase-admin")
const nodemailer = require('nodemailer');

admin.initializeApp()


//google account credentials used to send email
var transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        user: '*****@****.com',
        pass: '***********'
    }
});


exports.sendMail = functions.https.onRequest((req, res) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Content-Type");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");        

    console.log(req.body['data']);
    const mailOptions = {
        from: `•••••••••@gmail.com`,
        to: req.body['data'].email,
        subject: 'contact form message',
        html: `<h2 style="color: teal">Order Confirmation</h2>
                            <a href="https://track-acquintances.firebaseapp.com/signup/${req.body.superu}">
                               <b> Register </b>"<br>
                            </a>`
    };


    return transporter.sendMail(mailOptions, (error, data) => {
        if (error) {
            return res.status(200).json({data: error.message});
        }
        data = JSON.stringify(data)
        return res.status(200).json({data: data});
    });

});

The problem is I can't access the passed email data and the function fails. I logged req.body['data'] to the functions logs and I see { email: 'xxx@xx.xxx.x', superu: true }. But I tried both req.body['data'].email and req.body['data']['email'] and they both doesn't work. And in my browsers console I get {data: "No recipients defined"}. Any help would be appreciated. Thank you

标签: javascriptfirebasevue.jsgoogle-cloud-functions

解决方案


You're confusing two types of Cloud Functions:

  • Your Cloud Function is defined as an HTTPS triggered function, which means that you can invoke it by accessing its URL in a browser, by calling fetch, or by using XMLHTTPRequest.

  • Your client code, tries to invoke a so-called Callable Cloud Function, which is a different type. While Callable Cloud Functions are also invoked directly over HTTPS, they have a specific wire protocol for being invoked.

Since the two types of function don't match, your client code is passing the parameters in a different format than what the server is handling.

You'll need to either call the HTTPS function, or convert the Cloud Function to be Callable. The latter would look something like:

exports.sendMail = functions.https.onCall((data, context) => {
  const email = data.email;
  const superu = data.superu;

  ...
});

推荐阅读