Importing firebase in node.js for cloud functions - node.js

I was following a tutorial for writing cloud functions, i tried to import firebase and use firebase.auth() as used in tutorial, but i am getting the below error.
⚠ Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /home/sankethbk7777/Desktop/React/Projects/social-ape/my-code/social-ape/functions/node_modules/firebase/package.json
at throwExportsNotFound (internal/modules/esm/resolve.js:299:9)
at packageExportsResolve (internal/modules/esm/resolve.js:522:3)
at resolveExports (internal/modules/cjs/loader.js:449:36)
at Function.Module._findPath (internal/modules/cjs/loader.js:489:31)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:875:27)
at Function.Module._load (internal/modules/cjs/loader.js:745:27)
at Module.require (internal/modules/cjs/loader.js:961:19)
at require (internal/modules/cjs/helpers.js:92:18)
at Object.<anonymous> (/home/sankethbk7777/Desktop/React/Projects/social-ape/my-code/social-ape/functions/index.js:19:18)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
⚠ We were unable to load your functions code. (see above)
code
functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const app = require('express')();
admin.initializeApp();
const config = {
apiKey: 'AIzaSyDMFe1IwnLoui-Meue-FMwNhc1k-MB8vc8',
authDomain: 'socialape-d306c.firebaseapp.com',
projectId: 'socialape-d306c',
storageBucket: 'socialape-d306c.appspot.com',
messagingSenderId: '705972174784',
appId: '1:705972174784:web:1ed87302a774bd1cef1225',
};
const firebase = require('firebase');
firebase.initializeApp(config);
// Signup route
app.post('/signup', (req, res) => {
const newUser = {
email: req.body.email,
password: req.body.password,
confirmPassword: req.body.confirmPassword,
handle: req.body.handle,
};
// TODO: validate date
firebase
.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then((data) => {
return res
.status(201)
.json({ message: `user ${data.user.uid} signed up successfully` });
})
.catch((err) => {
console.log(err);
return res.status(500).json({ error: err.code });
});
});
// To tell firebase cloud functions to use routes on express app
// we have written api because we want all our API URL's to start with /api.
exports.api = functions.https.onRequest(app);
I know import could be little different because of version change (the tutorial is from 2019) but i am not able to fix it. Please help me

You should use the Admin SDK in a Cloud function and not the client. That being said you can remove the const firebase = require("firebase") and firebase.initializeApp(config); along with the client configuration. To create users, you can use the createUser() method:
app.post('/signup', (req, res) => {
const newUser = {
email: req.body.email,
password: req.body.password,
confirmPassword: req.body.confirmPassword,
handle: req.body.handle,
};
return admin.auth().createUser({ email, password }).then((userRecord) => {
return res.send(`Created user ${userRecord.uid}`)
})
}
I am not sure what the 'handle' is but you can use Custom Claims or any database to store it.
Do note that creating users in a Cloud function or a server environment won't log the user in automatically. You must redirect users to your login page after returning the response.

Related

Firebase Admin SDK network app/network-error

I have the following nodejs script.
const admin = require("firebase-admin")
admin.initializeApp({
credential: admin.credential.cert("./serviceAccountKey.json"),
databaseURL: "https://<ProjectID>.firebaseio.com/"
})
const uid = "5mP5FvjjCKcJ1IBXfV3rpChd3ob2"
admin
.auth()
.setCustomUserClaims(uid, { role: 'admin' })
.then(() => {
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
console.log(`Admin claim added to ${uid}`)
})
.catch((err) => console.log(err))
When I run the script I get the following error.
{
errorInfo: {
code: 'app/network-error',
message: 'Error while making request: connect ECONNREFUSED 127.0.0.1:9099. Error code: ECONNREFUSED'
},
codePrefix: 'app'
}
What am I doing wrong here?
Also, my firebase project has the spark plan.

Firebase Functions - FirebaseError: Missing required options (force) while running in non-interactive mode

I have a Firebase Function that deletes a user's collection in a Firestore database when their account is deleted.
const firebase_tools = require("firebase-tools");
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.deleteUser = functions.auth.user().onDelete((user) => {
return firebase_tools.firestore
.delete(`users/${user.uid}`, {
project: process.env.GCLOUD_PROJECT,
token: functions.config().fb.token,
recursive: true,
yes: true
}).catch((error) => {
console.log(error);
throw new functions.https.HttpsError(
"unknown",
"Error deleting user's data"
);
});
});
Whenever a user is deleted and the function is executed, I get the following error in the Functions logs.
FirebaseError: Missing required options (force) while running in non-interactive mode
at prompt (/workspace/node_modules/firebase-tools/lib/prompt.js:16:15)
at promptOnce (/workspace/node_modules/firebase-tools/lib/prompt.js:29:11)
at Command.actionFn (/workspace/node_modules/firebase-tools/lib/commands/firestore-delete.js:69:51)
at Object.delete (/workspace/node_modules/firebase-tools/lib/command.js:190:25)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
The only information I could find related to this is regarding deploying/deleting functions to Firebase and there's not much documentation for firebase-tools that I could find.
Add force: true to the JSON passed to firebase-tools. Worked for me with version 10.1.4
{
project: process.env.GCLOUD_PROJECT,
token: functions.config().fb.token,
recursive: true,
yes: true,
force: true // add this
}
I've reproduced the error that you have encountered.
This error occurs on the latest "firebase-tools": "^10.1.3".
Based on the Delete data with a Callable Cloud Function, the documentation have sample code that still uses "firebase-tools": "9.18.0".
You could downgrade your firebase-tools by modifying the package.json. E.g. below:
"dependencies": {
"firebase": "^9.6.5",
"firebase-admin": "^9.12.0",
"firebase-functions": "^3.16.0",
"firebase-tools": "9.18.0"
}
After downgrading, I'm able to delete the specified document successfully.
You could also use what's #Renaud Tarnec answered by using Admin SDK.
E.g. below:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
db = admin.firestore();
exports.deleteUser = functions.auth.user().onDelete((user) => {
db.collection("users").doc(user.uid).delete()
.then(function(user) {
console.log("Successfully Deleted User:", user.uid)
})
.catch((error) => {
console.log(error);
throw new functions.https.HttpsError(
"unknown",
"Error deleting user's data"
);
});
});

how did this forked in the rest api route go wrong?

Update: This problem was solved. I followed the advice of the replies and tried the console.log(req.body) command. Turns out it was calling a different function. Now at the time I was using postman to test the API and I learned that editing an already saved function is not the same as with other text or media editors and you have to make a completely new function to test it. I.E. I used a previous post function to create user and changed some elements, turns out postman doesnt like that and just ran the old function.
Thanks for the help everyone
I made an admin route using an already working user route exactly except using fewer values.
I keep getting an undefined error during validation when ever I try to run a post function. what could have gone wrong here? Or where should I look for the error, I checked the spellings of each of the values Iam using in the create admin function but I see no spelling problems?
Error in Console:
Error: admin validation failed: AdminEMail: Path `AdminEMail` is required., AdminPassword: Path `AdminPassword` is required.
at ValidationError.inspect (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\error\validation.js:48:26)
at formatValue (internal/util/inspect.js:563:31)
at inspect (internal/util/inspect.js:221:10)
at formatWithOptions (internal/util/inspect.js:1693:40)
at Object.Console.<computed> (internal/console/constructor.js:272:10)
at Object.log (internal/console/constructor.js:282:61)
at D:\Downloads\Compressed\api-master_3\api-master\routes\Admin.js:25:21
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\model.js:4876:16
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\helpers\promiseOrCallback.js:16:11
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\model.js:4899:21
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\model.js:493:16
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:246:48
at next (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:167:27)
at next (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:169:9)
at Kareem.execPost (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:217:3)
at _handleWrapError (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:245:21) {
errors: {
AdminEMail: ValidatorError: Path `AdminEMail` is required.
at validate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1178:13)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1161:7
at Array.forEach (<anonymous>)
at SchemaString.SchemaType.doValidate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1106:14)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\document.js:2379:18
at processTicksAndRejections (internal/process/task_queues.js:76:11) {
properties: [Object],
kind: 'required',
path: 'AdminEMail',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
},
AdminPassword: ValidatorError: Path `AdminPassword` is required.
at validate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1178:13)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1161:7
at Array.forEach (<anonymous>)
at SchemaString.SchemaType.doValidate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1106:14)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\document.js:2379:18
at processTicksAndRejections (internal/process/task_queues.js:76:11) {
properties: [Object],
kind: 'required',
path: 'AdminPassword',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'admin validation failed'
}
And Here is the route:
//Imported modules
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
//Imported models
const Admin = require('../models/admin');
//const User = require('../models/user');
router.get('/', (req,res) =>{
res.send("We are on Admin");
})
//Admin Functions
//Creation of new Admin
router.post("/signup", (req,res) => {
const admin = new Admin({
_id: new mongoose.Types.ObjectId(),
AdminEMail: req.body.AdminEMail,
AdminPassword: req.body.AdminPassword
});
admin.save(function(err,admin){
if(err){
console.log(err);
res.send(err);
return
}
console.log("New admin created");
res.send(admin);
})
})
//Admin Login and verification
router.post("/login", (req,res) => {
const AdminID = req.body.AdminID;
const Username = req.body.username;
const Password = req.body.password;
Admin.findOne({_id:AdminID}, function(err, foundAdmin){
if(err){
res.send("<h1>got clicked</h1>");
console.log(err);
}else{
if(foundAdmin){
if(foundAdmin.AdminEMail === Username){
if(foundAdmin.AdminPassword === Password){
res.send("logged in");
}
else{
res.send("Username and Password Mismatch");
}
}
else{
res.send("Username and ID Mismatch");
}
}
else{
res.send("No Such admin exists");
}
}
});
});
//
module.exports = router;

Keep getting the "ConfigError: Missing region in config" error in Node.js no matter what I do

I keep getting the "UnhandledPromiseRejectionWarning: ConfigError: Missing region in config" when trying to make requests to APIs I have set up in Node.js.
I'm new to DynamoDB and after setting up most of my boilerplate code I'm using Postman to test my routes. However I keep getting the same error each time I make a post request. I've checked some solutions on existing threads, namely: Configuring region in Node.js AWS SDK but cannot get it to work.
I am currently developing the app locally and checked the database where the items are being added.
My setup is as follows:
// user_controller.js
const uuid = require('uuid');
const sanitizer = require('validator');
const bcrypt = require('bcryptjs-then');
const AWS = require('aws-sdk');
const config = require('../config/config');
const { signToken, userByEmail, userById } = require('../Helpers/Users');
const isDev = true
Then in my code block I have the following:
// user_controller.js
(...)
if (isDev) {
AWS.config.update(config.aws_local_config);
} else {
AWS.config.update(config.aws_remote_config);
}
const DB = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: config.aws_table_name,
Item: {
userId: await uuid.v1(),
firstName: sanitizer.trim(firstName),
lastName: sanitizer.trim(lastName),
email: sanitizer.normalizeEmail(sanitizer.trim(email)),
password: await bcrypt.hash(password, 8),
level: 'standard',
createdAt: new Date().getTime(),
updatedAt: new Date().getTime(),
},
}
return userByEmail(params.Item.email) // Does the email already exist?
.then(user => { if (user) throw new Error('User with that email exists') })
.then(() => DB.put(params).promise()) // Add the data to the DB
.then(() => userById(params.Item.id)) // Get user data from DB
.then(user => (err, data) => {
console.log("AFTER USER CREATED")
if (err) {
res.send({
success: false,
message: 'Error: Server error'
});
} else {
console.log('data', data);
res.send({
statusCode: 201,
message: 'Success - you are now registered',
data: { token: signToken(params.Item.id), ...user },
});
}
})
(...)
Finally I am importing the config from separate file:
// config.js
module.exports = {
aws_table_name: 'usersTable',
aws_local_config: {
region: 'local',
endpoint: 'http://localhost:8000'
},
aws_remote_config: {}
}
In have already configured the aws-sdk:
AWS Access Key ID [****************foo]:
AWS Secret Access Key [****************bar]:
Default region name [local]:
Default output format [json]:
Here is the output I keep getting:
(node:4568) UnhandledPromiseRejectionWarning: ConfigError: Missing region in config
at Request.VALIDATE_REGION (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/event_listeners.js:92:45)
at Request.callListeners (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at callNextListener (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/sequential_executor.js:96:12)
at /Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/event_listeners.js:86:9
at finish (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:350:7)
at /Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:368:9
at SharedIniFileCredentials.get (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/credentials.js:127:7)
at getAsyncCredentials (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:362:24)
at Config.getCredentials (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:382:9)
at Request.VALIDATE_CREDENTIALS (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/event_listeners.js:81:26)
(node:4568) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:4568) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Like I said, I've tried a lot of variations on this but to no avail. Would love some help, thanks.
I dont know if this helps, but I used none instead of local for the region and it seemed to work for me
AWS.config.update({ region: 'none' })

Nodemailer error while using gmail in firebase functions

I am using firebase cloud functions. I have the following setup configured. While that is working completely fine on my local machine, It's giving me an issue when run on the servers. I have tried gazillion work arounds on the internet but no luck. What is wrong with this?
'use strict'
const functions = require('firebase-functions');
var admin = require('firebase-admin');
const express = require('express');
const nodemailer = require('nodemailer');
const app = express()
var emailRecepient;
var userName;
const smtpTransport = nodemailer.createTransport({
service: "gmail",
host: 'smtp.gmail.com',
port: 587, // tried enabling and disabling these, but no luck
secure: false, // similar as above
auth: {
user: '<emailid>',
pass: '<password>'
},
tls: {
rejectUnauthorized: false
}
});
var mailOptions = {
from: 'test <hello#example.com>',
to: emailRecepient,
subject: 'Welcome to test',
text: 'welcome ' + userName + ". did you see the new things?"
};
function sendmail() {
smtpTransport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
}
else {
console.log('Email sent: ' + info.response);
}
});
};
exports.sendEmails = functions.database.ref('/users/{userID}/credentials').onCreate((snap, context) => {
const userID = context.params.userID;
const vals = snap.val()
userName = vals.name;
emailRecepient = vals.email;
smtpTransport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log("Error sending email ---- ",error);
}
else {
console.log('Email sent: ' + info.response);
}
});
return true;
});
The error I got on all cases is :
Error sending email 2 ---- { Error: Invalid login: 534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbsi
534-5.7.14 qRQLfD9YlFZDsPj7b8QQACro9c41PjhSVo0NZ4i5ZHNlyycFi_FyRp8VdZ_dH5ffWWAABQ
534-5.7.14 8rH2VcXkyZBFu00-YHJUQNOqL-IqxEsZqbFCwCgk4-bo1ZeDaKTdkEPhwMeIM2geChH8av
534-5.7.14 0suN293poXFBAk3TzqKMMI34zCvrZlDio-E6JVmTrxyQ-Vn9Ji26LaojCvdm9Bq_4anc4U
534-5.7.14 SpQrTnR57GNvB0vRX1BihDqKuKiXBJ5bfozV1D1euQq18PZK2m> Please log in via
534-5.7.14 your web browser and then try again.
534-5.7.14 Learn more at
534 5.7.14 https://support.google.com/mail/answer/78754 t2sm3669477iob.7 - gsmtp
at SMTPConnection._formatError (/user_code/node_modules/nodemailer-smtp-transport/node_modules/smtp-connection/lib/smtp-connection.js:528:15)
at SMTPConnection._actionAUTHComplete (/user_code/node_modules/nodemailer-smtp-transport/node_modules/smtp-connection/lib/smtp-connection.js:1231:30)
at SMTPConnection.<anonymous> (/user_code/node_modules/nodemailer-smtp-transport/node_modules/smtp-connection/lib/smtp-connection.js:319:22)
at SMTPConnection._processResponse (/user_code/node_modules/nodemailer-smtp-transport/node_modules/smtp-connection/lib/smtp-connection.js:669:16)
at SMTPConnection._onData (/user_code/node_modules/nodemailer-smtp-transport/node_modules/smtp-connection/lib/smtp-connection.js:493:10)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at TLSSocket.Readable.push (_stream_readable.js:134:10)
at TLSWrap.onread (net.js:559:20)
code: 'EAUTH',
response: '534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbsi\n534-5.7.14 qRQLfD9YlFZDsPj7b8QQACro9c41PjhSVo0NZ4i5ZHNlyycFi_FyRp8VdZ_dH5ffWWAABQ\n534-5.7.14 8rH2VcXkyZBFu00-YHJUQNOqL-IqxEsZqbFCwCgk4-bo1ZeDaKTdkEPhwMeIM2geChH8av\n534-5.7.14 0suN293poXFBAk3TzqKMMI34zCvrZlDio-E6JVmTrxyQ-Vn9Ji26LaojCvdm9Bq_4anc4U\n534-5.7.14 SpQrTnR57GNvB0vRX1BihDqKuKiXBJ5bfozV1D1euQq18PZK2m> Please log in via\n534-5.7.14 your web browser and then try again.\n534-5.7.14 Learn more at\n534 5.7.14 https://support.google.com/mail/answer/78754 t2sm3669477iob.7 - gsmtp',
responseCode: 534,
command: 'AUTH PLAIN' }
I have even turned of the allow secure apps in the google settings. But for some reason this doesn't seem to work. Any help is extremely appreciated.
As advised by Renaud, I tried firebase-samples/email-confirmation and I am having following error :
TypeError: snapshot.changed is not a function
at exports.sendEmailConfirmation.functions.database.ref.onWrite (/user_code/index.js:38:17)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
at /var/tmp/worker/worker.js:758:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
Cheers
When you execute an asynchronous operation in a background triggered Cloud Function, you must return a promise, in such a way the Cloud Function waits that this promise resolves in order to terminate.
This is very well explained in the official Firebase video series here: https://firebase.google.com/docs/functions/video-series/. In particular watch the three videos titled "Learn JavaScript Promises" (Parts 2 & 3 especially focus on background triggered Cloud Functions, but it really worth watching Part 1 before).
So you should modify your code as follows:
exports.sendEmails = functions.database.ref('/users/{userID}/credentials').onCreate((snap, context) => {
const userID = context.params.userID;
const vals = snap.val()
userName = vals.name;
emailRecepient = vals.email;
return smtpTransport.sendMail(mailOptions);
});
If you want to print to the console the result of the email sending, you can do as follows:
return smtpTransport.sendMail(mailOptions)
.then((info) => console.log('Email sent: ' + info.response))
.catch((error) => console.log("Error sending email ---- ", error));
});
Actually there is an official Cloud Functions sample that does exactly that, see https://github.com/firebase/functions-samples/blob/master/email-confirmation/functions/index.js
I see it was a long discussion, let me share the code snippets which worked out for me for others with similar issues so it will be easier to figure out.
1) function.ts (it's written in TypeScript)
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
import * as nodemailer from 'nodemailer';
admin.initializeApp();
// I'm taking all these constants as secrets injected dynamically (important when you make `git push`), but you can simply make it as a plaintext.
declare const MAIL_ACCOUNT: string; // Declare mail account secret.
declare const MAIL_HOST: string; // Declare mail account secret.
declare const MAIL_PASSWORD: string; // Declare mail password secret.
declare const MAIL_PORT: number; // Declare mail password secret.
const mailTransport = nodemailer.createTransport({
host: MAIL_HOST,
port: MAIL_PORT, // This must be a number, important! Don't make this as a string!!
auth: {
user: MAIL_ACCOUNT,
pass: MAIL_PASSWORD
}
});
exports.sendMail = functions.https.onRequest(() => {
const mailOptions = {
from: 'ME <SENDER#gmail.com>',
to: 'RECEIVER#gmail.com',
subject: `Information Request from ME`,
html: '<h1>Test</h1>'
};
mailTransport
.sendMail(mailOptions)
.then(() => {
return console.log('Mail sent'); // This log will be shown in Firebase Firebase Cloud Functions logs.
})
.catch(error => {
return console.log('Error: ', error); // This error will be shown in Firebase Cloud Functions logs.
});
});
This said, you should receive an e-mail from SENDER#gmail.com to RECEIVER#gmail.com, of course modify it for your own needs.
Note: I got the same issue with sending mails correctly on localhost, but on deployment it did not. Looks like the problem in my case was that I did not use port and host in createTransport, instead I had:
const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: MAIL_ACCOUNT,
pass: MAIL_PASSWORD
}
});
On top of this do not forget about enabling Less secure app access to ON. Also https://accounts.google.com/DisplayUnlockCaptcha might be helpful.
After checking that all the things listed above were done within my code, I solved the problem login in Google´s account (with the account I'm using with my proyect). I had to recognize the activity form another origin (google detected Firebase was trying to access to that account), and that was it.
After that I tryed to send another email from firebase cloud and it was working fine

Resources