I am developing a simple contact form by using Angular9 + Firebase. I have no idea how to get the values from the contact form in the Firebase Function.
I tried it in many ways, but I always get the “undefined” value. The following is my code. Please give me the solution if anybody knows how to do. Thank you.
Frontend
import { AngularFireFunctions } from '@angular/fire/functions';
constructor(
private angularFireFunctions: AngularFireFunctions
) {}
submitContact(e: Event) {
e.preventDefault();
// Send Email Setup
const contactJson = JSON.stringify(this.contact);
const mailer = this.angularFireFunctions.httpsCallable('sendMail');
mailer(contactJson).subscribe(
(resp) => {
console.log({ resp });
},
(err) => {
console.error({ err });
}
);
return;
}
When the submit button is clicked, contactJson looks like this:
{"name":"Your Name","email":"youremailaddress@gmail.com","message":"Hello This is your message"}
Firebase Functions – index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as nodemailer from 'nodemailer';
const cors = require('cors')({ origin: true });
admin.initializeApp();
const transporter = nodemailer.createTransport({
host: 'Your Host',
port: 465,
secure: true,
auth: {
user: 'Your Email Account',
pass: 'Your Password',
},
});
export const sendMail = functions.https.onRequest((request, response) => {
const name = request.body.name;
const email = request.body.email;
const message = request.body.message;
return cors(request, response, () => {
const text = `
Name - ${name}
Email - ${email}
Message - ${message}`;
const mailOptions = {
from: 'Your Email Address',
to: 'Customers Email Address',
subject: 'We received your inquiry',
text: text,
};
transporter.sendMail(mailOptions, (erro, info) => {
console.info(erro, info);
if (erro) {
response.send({ error: 'error' });
}
response.send({ data: 'success' });
});
});
});
The following is the email body I receive. Each value is “undefined”.
Name - undefined Email - undefined Message - undefined
In the end of the process, the google chrome console get the success message
{resp: "success"}
Version Info
Angular CLI: 9.0.7
Node: 10.15.3
OS: win32 x64
Angular: 9.0.7
animations, cli, common, compiler, compiler-cli, core, forms
language-service, localize, platform-browser
platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.7
@angular-devkit/build-angular 0.900.7
@angular-devkit/build-optimizer 0.900.7
@angular-devkit/build-webpack 0.900.7
@angular-devkit/core 9.0.7
@angular-devkit/schematics 9.0.7
@angular/fire 6.0.2
@ngtools/webpack 9.0.7
@schematics/angular 9.0.7
@schematics/update 0.900.7
rxjs 6.5.5
typescript 3.7.5
webpack 4.41.2
Advertisement
Answer
The way you’re gathering the information only works for the Content-Type
of application/json
, so first to determine if you’re indeed sending this specific content type, you can do that with request.get('content-type')
:
export const sendMail = functions.https.onRequest((request, response) => {
response.send(req.get('content-type'));
)};
Or by using this example on the documentation that emcompasses almos all types of HTTP requests:
const escapeHtml = require('escape-html');
/**
* Responds to an HTTP request using data from the request body parsed according
* to the "content-type" header.
*
* @param {Object} req Cloud Function request context.
* @param {Object} res Cloud Function response context.
*/
exports.helloContent = (req, res) => {
let name;
switch (req.get('content-type')) {
// '{"name":"John"}'
case 'application/json':
({name} = req.body);
break;
// 'John', stored in a Buffer
case 'application/octet-stream':
name = req.body.toString(); // Convert buffer to a string
break;
// 'John'
case 'text/plain':
name = req.body;
break;
// 'name=John' in the body of a POST request (not the URL)
case 'application/x-www-form-urlencoded':
({name} = req.body);
break;
}
res.status(200).send(`Hello ${escapeHtml(name || 'World')}!`);
};
The only type that seems to be missing is the case of Multipar-Form
, this specific type could be done with this example on the documentation