Reputation: 11
I followed this tutorial but i use nodemailer instead of sendgrid.
https://www.youtube.com/watch?v=wCtNjP9gcqk
Im getting this error
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:4200' is therefore not allowed access. The response had HTTP status code 500
I´ve tried several solution on the internet..
The most logic i found was this one...
https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html
But i keep getting the error
This is what i have on the server side / firebase functions..
const nodemailer = require('nodemailer');
const functions = require('firebase-functions');
const cors = require('cors')({
origin: true
});
function sendFn(req, res) {
var transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: "user@gmail.com",
pass: "password"
}
});
var mailOptions = {
from: '', // sender address (who sends)
to: '', // list of receivers (who receives)
subject: '', // Subject line
replyTo: '',
text: '', // plaintext body
html: '' // html body
};
mailOptions['from'] = 'Contact';
mailOptions['to'] = 'address@email.com';
mailOptions['text'] = req.query.msg;
mailOptions['replyTo'] = req.query.email;;
mailOptions['subject'] = "WebContact - " + req.query.name;
// // send mail with defined transport object
return transporter.sendMail(mailOptions).then(() => {
console.log('Email sent to:');
}).catch(error => {
console.error('There was an error while sending the email:', error);
});
};
exports.httpEmail = functions.https.onRequest((req, res) => {
var corsFn = cors();
corsFn(req, res, function() {
sendFn(req, res);
});
});
This is what i've got on the front ... im using angular...
const url = `firebase.url.function`;
const params: URLSearchParams = new URLSearchParams();
const headers = new Headers({ 'Content-Type': 'application/json'. , 'Access-Control-Allow-Origin': '*'});
const options = new RequestOptions({ headers: headers });
params.set('name', data['name']);
params.set('email', data['email']);
params.set('msg', data['msg']);
console.log('Enviados' + params);
this.http.post(url, params, options)
.toPromise()
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
Im lost how to change or set the cors on the firebase side ...
Thanks a lot
----EDIT----
Firebase Log.
TypeError: Cannot read property 'headers' of undefined
at /user_code/node_modules/cors/lib/index.js:219:31
at optionsCallback (/user_code/node_modules/cors/lib/index.js:199:9)
at corsMiddleware (/user_code/node_modules/cors/lib/index.js:204:7)
at exports.httpEmail.functions.https.onRequest (/user_code/index.js:54:18)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:26:41)
at /var/tmp/worker/worker.js:635:7
at /var/tmp/worker/worker.js:619:9
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
Upvotes: 1
Views: 3164
Reputation: 427
I had the same issue but used React for the front-end part. I managed to fix the issue by doing these steps:
Set these cors options when importing it
const cors = require('cors');
const corsOptions = {
origin: '*',
allowedHeaders: ['Content-Type', 'Authorization', 'Content-Length', 'X-Requested-With', 'Accept'],
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
When you try to send mail with nodemailer and use your Google credentials(email, password) Google will block the request because it is suspicious. So in order to send the mail using your Gmail account, you have to do the following:
In the Authorized redirect URIs section add: https://developers.google.com/oauthplayground and https://developers.google.com/oauthplayground/ You can add only the one without the trailing slash, but I added them both because had some issues using only the one without the slash at the end.
Click save(make sure settings are saved, you will be redirected)
Now go to https://developers.google.com/oauthplayground/
Click on the settings button (the little cog) on the right and make sure you fill in your client id and secret there like shown on the screen.
After you are finished with this go to the Select and Authorize APIs and find the Gmail API and authorize it.
If everything is okay you will be redirected to log in with your Google account. Login, then allow access to your app and you will be redirected again to the OAuth playground and check out Exchange authorization code for tokens tab:
Copy the refresh token!
Then configure your Nodemailer transport settings like so:
const mailTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
type: 'OAuth2',
user: 'xxxxxx@gmail.com', // the email you signed on the auth playground
clientId: 'cliend id here',
clientSecret: 'client secret here',
refreshToken: 'refresh token here'
}
});
And here is my working Cloud Function:
exports.bookNow = functions.https.onRequest((req, res) => {
const corsMiddleware = cors(corsOptions);
corsMiddleware(req, res, () => {
mailTransport.sendMail({
from: `blabla@gmail.com`, // sender address
to: 'blah@gmail.com', // list of receivers
subject: `You have got a new email!`, // Subject line
html: `<div>Email body here</div>`
}).then((info) => {
res.status(200).send({ message: "Email sent"})
}).catch(error => {
res.send(error)
});
});
});
This is working for me, I hope works for you and the other ones who struggle! Good luck!
Upvotes: 1