Im having an annoying problem which i've spent most of my day trying to solve without any luck - Also tried searching for a solution here and on Google, but without any luck, or at least all solution tried out didn't work.
When running my function, the firebase function log is telling me:
Cannot find module 'mailgun.js'
I have no idea why it won't resolve the module as it exist in the package.json file.
From the package.json:
"dependencies": {
"cors": "^2.8.5",
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1",
"form-data": "^4.0.0",
"mailgun.js": "^4.1.4"
},
I've have done a npm install inside the functions folder, and it deploys without problems, so the problem is when calling the function...
The code is:
import * as functions from "firebase-functions";
import Mailgun from "mailgun.js";
// eslint-disable-next-line #typescript-eslint/no-var-requires
const formData = require("form-data");
const domain = "https://app.mailgun.com/app/sending/domains/sandboxae7cd087b3854d25a6933f1fe489b5e3.mailgun.org";
const mgClient = new Mailgun(formData);
const mg = mgClient.client({
key: "mykey",
username: "api",
public_key: "mypublickey",
});
export const sendWelcomeEmailToClient = functions.https.onCall(
async (email: string) => {
return mg.messages.create(domain, {
from: "Task System",
to: email,
subject: "Testing",
html: "Dette er en test",
});
}
);
Please note, i've also tried doing a require instead of import on mailgun.js like so, but didn't work either:
Also, the mailgun documentation says that is the way to import it: https://www.npmjs.com/package/mailgun.js
const Mailgun = require("mailgun.js");
Solved it by using SendGrid instead of MailGun, that works as a charm...
Related
Trying to work with node/javascript/nfts, I am a noob and followed along a tutorial, but I get this error:
error [ERR_REQUIRE_ESM]: require() of ES Module [...] is not supported. Instead change the require of index.js [ in my file...] to a dynamic import() which is available in all CommonJS modules
My understanding is that they've updated the node file, so i need a different code than that in the tutorial, but i don't know which one I'm supposed to change, where and to what. Please be as specific as you can
const FormData = require('form-data');
const fetch = require('node-fetch');
const path = require("path")
const basePath = process.cwd();
const fs = require("fs");
fs.readdirSync(`${basePath}/build/images`).foreach(file).forEach(file => {
const formData = new FormData();
const fileStream = fs.createReadStream(`${basePath}/build/images/${file}`);
formData.append('file',fileStream);
let url = 'https://api.nftport.xyz/v0/files';
let options = {
method: 'POST',
headers: {
Authorization: '[...]',
},
body: formData
};
fetch(url, options)
.then(res => res.json())
.then(json => {
const fileName = path.parse(json.file_name).name;
let rawdata = fs.readFileSync(`${basePath}/build/json/${fileName}.json`);
let metaData = JSON.parse(rawdata);
metaData.file_url = json.ipfs_url;
fs.writeFileSync(`${basePath}/build/json${fileName}.json`, JSON.stringify(metaData, null, 2));
console.log(`${json.file_name} uploaded & ${fileName}.json updated!`);
})
.catch(err => console.error('error:' + err));
})
It is because of the node-fetch package. As recent versions of this package only support ESM, you have to downgrade it to an older version node-fetch#2.6.1 or lower.
npm i node-fetch#2.6.1
This should solve the issue.
This can occur when you install the latest version of a package that has an issue with modules import.
In my case, I was getting the error after installing the latest version of crypto-random-string package. To know which package is causing this error, check the message preceding the above error reported. In my case, it read like so:
error: uncaughtException: require() of ES Module /Users/myname/Documents/mydir/anotherdir/my-project/node_modules/crypto-random-string/index.js
To fix it, I only downgraded to an earlier version by doing the following:
yarn remove crypto-random-string
yarn add crypto-random-string#3.3.1
Go to your package.json file and write:
"type": "module",
above debug.
and instead of writing require('chalk') in the .js file, change it to import chalk from 'chalk'
I had this error on common.js in angular-devkit after upgrading to angular 13. I found that this is missed during the upgrade:
ng update does not check or update #angular-devkit packages
I got rid of it using:
ng update #angular-devkit/build-angular
No need to use the old version.
You can use this line instead of "require"
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
I added the one statement extra you can see this "type": "module", statement, written down after license.
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"chalk": "^5.0.1"
}
}
I have decided to use firebase as a backend for authentication and basic form information with firestore.
In the past I've used this express api in cloud functions to do this, and am basing this new setup off of that. But I'm looking to just use it on a Vultr Centos server instead, to put with the rest of my api, and just make everything easier for now as i don't want to overcomplicate things (until later :P).
Now - I've just cloned this repo onto my server, and I want to test it with postman, and i'm having trouble just accessing it.
I'm not sure how to solve the issue and if anyone could point me in the right direction that would make my life so much easier!
here is the index file and the package json file currently. I've created the server.listen to try and make it work at the moment.
const functions = require("firebase-functions");
const app = require("express")();
const FBAuth = require("./util/fbAuth");
const server = require('http').createServer(app);
const cors = require("cors");
//This was recently added to try and make it all work easier!
server.listen(port, ipaddress, () => {
});
app.use(cors());
const { db } = require("./util/admin");
const {
getAllWorkflows,
...
} = require("./handlers/workflow");
const {
signup,
login,
uploadImage,
addUserDetails,
getAuthenticatedUser,
getUserDetails
} = require("./handlers/users");
// Workflow Routes
app.get("/Workflows", getAllWorkflows);
...
// user route
app.post("/user", FBAuth, addUserDetails);
app.post("/user/image", FBAuth, uploadImage);
...
// cloud functions are better than firebase library because of load time.
exports.api = functions.https.onRequest(app);
here is the package.json file.
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "10"
},
"dependencies": {
"busboy": "^0.3.1",
"cors": "^2.8.5",
"express": "^4.17.1",
"firebase": "^7.21.1",
"firebase-admin": "^8.9.0",
"firebase-functions": "^3.11.0",
"firebase-tools": "^7.11.0"
},
"devDependencies": {
"firebase-functions-test": "^0.1.6",
"node-gyp": "^5.0.7"
},
"private": true
}
With the backend i am fixing up, I use this sort of workthrough (if it helps!), which I am replacing with firebase stuff above - if that makes sense. It works currently, is accessible for signup and login functionality, the key part for me is just using firebase and firestore with it.
const config = require('../../config');
const express = require('express');
const app = express();
const server = require('http').createServer(app);
.....
server.listen(config.serverParams.port, config.serverParams.address, () => {
console.log(`Server running at http://${server.address().address}:${server.address().port}`);
});
....
app.use((req,res,next)=>{
//can reaplce * with website we want to allow access
res.header('Access-Control-Allow-Origin', 'https://moodmap.app/stats');
next();
});
....
io.on('connection', socket => {
socket.use((packet, next) => {
.....
});
});
Really appreciate any guidance on this matter!
Firebase and firestore seems like a nice way to avoid reinventing the wheel, if only i could simply type npm start, and begin testing with postman the underlying functionality :s
The API is based off another side project i did, which is largely here for those interested in exploring it more.
https://github.com/Hewlbern/LightSpeed/tree/master/sigops
Very happy to just use the easiest way forward - I don't want to have any of the libraries on the client side though, as i want to make my front end super efficient. Thanks!
Cloud Functions does not allow you to listen on any ports in order to receive requests. It automatically handles incoming connections using the URL automatically provided during deployment. All incoming requests to that URL are routed to your function callback defined by the exported function built by functions.https.onRequest().
If you require the ability to listen to specific ports, Cloud Functions is not the right product for your use case. Cloud Functions can not be deployed on custom servers - it only works on infrastructure provided by Google.
I am trying to add email to a firebase cloud function. However, when ever I add the line:
const nodemailer = require('nodemailer');
to index.js, code which previously deployed will no longer deploy. It reports that one of my functions had an error, but this can't be the case cause it works just fine with that function. Here is the full code, runs without the line just fine.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const nodemailer = require('nodemailer');
admin.initializeApp();
exports.routineKick = functions.pubsub
.schedule('every 2 minutes')
.timeZone('America/New_York')
.onRun(context => {
//kickMembers();
}
);
Posting the solution as a Community Wiki since this solution was shared by an edit to the question itself by the OP.
The problem is that the app was missing the nodemailer dependency. It can be fixed by doing the following:
In the package.JSON file, located at the functions folder, add under dependencies the following: "nodemailer": "^6.4.3" or whatever version you have.
I'm using node mailer version of 6.7.0, In the "package.JSON" file, downgrade node version from 14 to 10 works for me
"engines": {
"node": "10"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1",
"nodemailer": "^6.7.0"
},
I was using NPM #woocommerce/woocommerce-rest-api successfully to manage API requests to Woocommerce/ WP website.
Was using babel and CJS version:
const WooCommerceRestApi = require("#woocommerce/woocommerce-rest-api").default;
const api = new WooCommerceRestApi({
url: "http://example.com",
consumerKey: "ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumerSecret: "cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
version: "wc/v3"
});
But since Node 14 is offering a simple way to use ESM I have added the following configuration to the package.json, so I can use the import statement:
"type": "module"
So I should have been able to use this format:
import WooCommerceRestApi from "#woocommerce/woocommerce-rest-api";
const api = new WooCommerceRestApi({
url: "http://example.com",
consumerKey: "ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumerSecret: "cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
version: "wc/v3"
});
But now I get this error:
file:///xxxxxx/test.js:5
const api = new WooCommerceRestApi({
^
TypeError: WooCommerceRestApi is not a constructor
at file:///xxxxxxxx/test.js:5:13
at ModuleJob.run (internal/modules/esm/module_job.js:138:23)
at async Loader.import (internal/modules/esm/loader.js:178:24)
Why would that happen?
You may have already solved this, but I ran into this issue myself and it looks to me like the esm loader is defaulting to the cjs version of the library.
This worked for me:
import pkg from '#woocommerce/woocommerce-rest-api';
const WooCommerceRestApi = pkg.default;
Yes, it is not a pretty solution, but it might be helpful for others or inspire someone to explain further. ;)
I'm trying to run locally a node lambda to debug it. I am using Serverless and this launch config in vsCode
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/node_modules/.bin/sls",
"args": [
"invoke",
"local",
"--function",
"hello",
"--data",
"hello world"
]
}
]
}
My export.handler looks like this:
module.exports.handler = (event, context, callback) => {
if (event.triggerSource === CONSTANTS.TRIGGER_SOURCE) {
console.log("event = " + JSON.stringify(event));
const uri = process.env.SCT_URL_BASE;
const country = process.env.SCT_COUNTRY;
const username =
event.request.userAttributes[CONSTANTS.USER_ATTRIBUTES];
const codeP = event.request.codeParameter;
console.log("URI = " + url);
console.log("Code:" + codeP);
getUrlData(uri, country, username, codeP);
} else {
context.done(null, event);
}
};
When I run de debug mode it does nothing. Serverless does not throw any error, I just can not reach inside the function.
Also, there is another thing I can not understand. In serverless documentation it said:
--function or -f The name of the function in your service that you want to invoke locally. Required.
I don't know what they are refering in this, if a function that we call to run the lambda or the function that it is called when the lambda is called. In this case, the function that I am exporting is "handler" but it doesn't work either.
Thanks in advance.
I have used this approach and it works for me:
https://standardofnorms.wordpress.com/2017/12/03/locally-debugging-aws-lambdas-written-in-node-js/
The bad thing is that I would like to use serverless and not lambda-local package due to the greater community of serverless. Lambda-local works like charm though, so I send a big hug to its creator from here.
Answers to the first question are still very welcome.
EDIT: Ok, I figured this out.
Results that Serverless, as framework, uses a serverless.yml file when we need to add some configuration. There, I had to create the function I am going to run with the serverless command and then point it to the file where I have my handler. This is my serverles.yml right now:
service: serverless-simple
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs4.3
functions:
lambdaHandler:
handler: src/customMessageLambda.handler
events:
- http:
path: ping
Sure I have to research a little more on this file but I have solved my issue.
Hope this helps someone, sometime.