Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

app to mail form data to my inbox doesn't work correctly on Firebase

I think I'm missing something very simple here. I have a simple, one page node.js app that uses nodemailer to email any form data to my inbox.

My index.js file:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var nodemailer = require('nodemailer');

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '[email protected]',
        pass: 'mypassword'
    }
});

app.use(express.static('public')); //public folder with my html files
app.get('', function (req, res) {
    res.sendFile(__dirname + "/");
})

app.post('/', function (req, res) {
    response = {
        name: req.body.name,
        email: req.body.email,
        message: req.body.message
    };
    var mailClient = {
        from: '[email protected]',
        to: '[email protected]',
        subject: `Message from ${response.name}`,
        text: 'MyMessage'
    };
    transporter.sendMail(mailClient, function (error, info) {
        if (error) {
            console.log(error); //not happening
        } else {
            res.redirect("/success.html"); //also not happening
        }
    });
})

var server = app.listen(80, function () {
    var host = server.address().address
    var port = server.address().port
    console.log("App listening at http://%s:%s", host, port)
})

When I run this on my local machine using npm start in the root directory, the app runs perfectly fine on localhost. Nodemailer works properly; when I submit, my form data gets emailed to myself and I get redirected to my success page.

However, when I deploy this to Firebase, it seems the nodemailer part doesn't work. The page loads in with my static files, but when I try to submit anything via the form, the page simply refreshes (like when you have a submit button with bare html), instead of redirecting me to my success page and emailing data.

Is there something I need to change in my code to make it work with firebase?

Edit - no logs: enter image description here

like image 552
user7548189 Avatar asked Dec 09 '17 02:12

user7548189


2 Answers

Google requires a paid account in order to make use of "Outbound Networking". The Free Tier does not allow you to make outbound calls. This would include sending mail to a remote mail server (like sending an email to a Yahoo, Gmail, or Outlook account).

See their pricing page for more info.

Look for "Outbound Networking".

If you'd like to leverage Gmail's API, you should still be able to use nodemailer with firebase functions and achieve what you're looking for and remain on the Free Tier. A fully working example is already available in the firebase-samples repository! I would like to highlight what the linked tutorial mentions, which is that Gmail does have an email sending quota that you should be aware of.

like image 144
Swivel Avatar answered Oct 13 '22 04:10

Swivel


I tried to figure out problem in your code but didn't found any, I also have functionality to send email with verification code for authenticate/verify email id. For that I create one gmail id and gave that id/password for sending mail. Mails are sent from that gmail id with node.js when ever user register is email id we send email with veirfication code. My code is as under:

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
var bodyParser = require('body-parser');
var users = require('./users/route');

const app = express();
const nodemailer = require('nodemailer');
// Configure the email transport using the default SMTP transport and a GMail account.
// For other types of transports such as Sendgrid see https://nodemailer.com/transports/
// TODO: Configure the `gmail.email` and `gmail.password` Google Cloud environment variables.
const gmailEmail = '[email protected]';
const gmailPassword = 'password';
const gcm = require('node-gcm');
const mailTransport = nodemailer.createTransport(
        `smtps://${gmailEmail}:${gmailPassword}@smtp.gmail.com`);

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://myapp.firebaseio.com"
});
//admin.initializeApp(functions.config().firebase);

// Express middleware that validates Firebase ID Tokens passed in the Authorization HTTP header.
// The Firebase ID token needs to be passed as a Bearer token in the Authorization HTTP header like this:
// `Authorization: Bearer <Firebase ID Token>`.
// when decoded successfully, the ID Token content will be added as `req.user`.
const authenticate = (req, res, next) => {
    if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer')) {
        res.status(403).send('Unauthorized');
        return;
    }
    const idToken = req.headers.authorization.split('Bearer ')[1];
    admin.auth().verifyIdToken(idToken).then(decodedIdToken => {
        req.user = decodedIdToken;
        next();
    }).catch(error => {
        res.status(403).send('Unauthorized');
    });
};

app.get("/token", (req, res) => {

    res.status(200).send(admin.auth().applicationDefault());
    admin.auth().createCustomToken(req.query.uid)
            .then(function (customToken) {
                res.status(200).send(customToken);
            })
            .catch(function (error) {
                console.log("Error creating custom token:", error);
            });

});


// GET /api/verifyEmail?code="1234"
app.get('/verifyEmail', (req, res) => {

    // Get the one-time code from the query parameter.
    var verificationCode = req.query.code;
    var displayName = req.query.displayName;
    var email = req.query.email; //If GET request
    const mailOptions = {
        from: `Linkuni <[email protected]>`,
        to: email
    };

    // The user subscribed to the newsletter.
    mailOptions.subject = `Welcome to Linkuni`;
    mailOptions.text = `Hi ${displayName || ''}\n\n Welcome to Linkuni. We hope you will enjoy our service. Please enter this code:${verificationCode} into the app.\n\nThank you,\nLinkuni Team`;

    return mailTransport.sendMail(mailOptions).then(() => {
        console.log('Verification email sent to:', email);
    });
});

Hope this helps!! :)

like image 22
sschunara Avatar answered Oct 13 '22 03:10

sschunara