Node application runs on Heroku but not localhost - node.js

I have a simple REST API using MEAN. It's hosted on Heroku, and everything works well there. However, if I try to run it on localhost I get the following error:
TypeError: Parameter "url" must be a string, not undefined
at Url.parse (url.js:81:11)
at Object.urlParse [as parse] (url.js:75:5)
at module.exports (/Users/ricardotaboada/Desktop/sbackend/node_modules/mongodb/lib/url_parser.js:15:23)
at connect (/Users/ricardotaboada/Desktop/sbackend/node_modules/mongodb/lib/mongo_client.js:403:16)
at Function.MongoClient.connect (/Users/ricardotaboada/Desktop/sbackend/node_modules/mongodb/lib/mongo_client.js:227:3)
at Object.<anonymous> (/Users/ricardotaboada/Desktop/sbackend/server.js:15:21)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
Any idea what's going on? Thanks very much.
EDIT: Here is the code that connects to Mongo:
mongodb.MongoClient.connect(process.env.MONGODB_URI, function (err, database) {
if (err) {
console.log(err);
process.exit(1);
}
sbrdcontroller = new controller(database);
console.log("Database connection ready");
// Initialize the app.
var server = app.listen(process.env.PORT || 3000, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
});

Hard to say without seeing some code.
That said, from the error message it sounds like you're not passing a valid URL to connect to your mongodb.
EDIT:
Right, so based on your code, check the value of process.env.MONGODB_URI. You can do that from your heroku account or cli, or by console.log, but I'm betting it's not set on your heroku app. Depending on the Mongo addin you use, they use different environment variable names.

process.env.MONGODB_URI is undefined in your local environment which is why the error is being thrown.
Add this code before the database connection code:
var development = process.env.NODE_ENV !== 'production';
var mongo_url;
if (development) {
mongo_url = 'mongodb://localhost:27017/mydb';
}
else {
mongo_url = process.env.MONGODB_URI;
}
Then change:
mongodb.MongoClient.connect(process.env.MONGODB_URI, function (err, database) {
To:
mongodb.MongoClient.connect(mongo_url, function (err, database) {
Assuming your local Mongo database port was not changed, the local URL with port 27017 should work fine.
Now your code should work fine in both development and production.

Maybe dotenv module will be useful for you:
https://www.npmjs.com/package/dotenv

Related

Node Redis does not work on my windows computer even though the server is up and running

const express = require("express");
const redis = require("redis");
const app = express();
const client = redis.createClient({
url: "redis://admin123#ec2-35-182-15-126.ca-central-1.compute.amazonaws.com",
});
client.on("connect", function () {
console.log("redis connected");
console.log(`connected ${redisClient.connected}`);
});
client.on("error", (err) => {
console.log(err);
});
app.listen(process.env.PORT || 3000, () => {
console.log("Node server started");
});
The above code does not show any connection to redis server even though I have checked the EC2 redis instance by connecting using Redsmin.
hosting details in Redsmin
This is a very simple thing to do but the error that I get cannot be googled.
Node server started C:\Users\Sithira_105661\Desktop\Projects\Learning\Redis\node_modules#node-redis\client\dist\lib\client\index.js:387
return Promise.reject(new errors_1.ClientClosedError());
^
ClientClosedError: The client is closed
at Commander._RedisClient_sendCommand (C:\Users\Sithira_105661\Desktop\Projects\Learning\Redis\node_modules#node-redis\client\dist\lib\client\index.js:387:31)
at Commander.commandsExecutor (C:\Users\Sithira_105661\Desktop\Projects\Learning\Redis\node_modules#node-redis\client\dist\lib\client\index.js:160:154)
at Commander.BaseClass. [as set] (C:\Users\Sithira_105661\Desktop\Projects\Learning\Redis\node_modules#node-redis\client\dist\lib\commander.js:8:29)
at Object. (C:\Users\Sithira_105661\Desktop\Projects\Learning\Redis\redis.js:19:8)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
Help me understand the issue. Thanks in advance.
finally found the solution. I used node-redis 3.0.0 rather than 4 and the code works fine. I do not know why it does not work in latest node-redis . If any of you guys are getting this issue use node-redis 3
I used node-redis 3.1.2 rather than 4 and the code works fine.
Please check your ec2 redis connection
const client = redis.createClient({
url: "redis://username:password#ec2_endpoint:port",
});
Connection string format: redis[s]://[[username][:password]#][host][:port]
You are using a very old version of Redis, an abandoned project by Microsoft called OpenTech Redis.
I suggest you checkout Memurai.
Memurai is an up-to-date native Windows port of Redis that derives from that project (see this commit).
Memurai is also available with a free Developer Edition.
Disclaimer: I work in Memurai.
If you're using redis ^4.0.0, you can do this:
const { createClient } = require('redis');
const { REDIS_HOST_URL } = require('../config');
const client = createClient({ url: REDIS_HOST_URL });
(async () => {
await client.connect();
})();
client.on('connect', () => console.log('::> Redis Client Connected'));
client.on('error', (err) => console.log('<:: Redis Client Error', err));
You can read more on their documentation here.
I don't thing we should decrease the version from 4 to 3.
we can use -
const redis = require('redis');
const client = redis.createClient();
(async () => {
await client.connect();
})();
client.on('connect', () => console.log('Redis Client Connected'));
client.on('error', (err) => console.log('Redis Client Connection Error', err));
In version 4.0.1, we have to add .connect() to run redis.
They have migration guide
This is my code, but it seems to not work well.
async function connectRedis(){
try {
const redisURL = '<link-redis-provider>';
const client = createClient({
url: redisURL
});
await client.connect();
console.log('Cache is ready');
} catch (error) {
console.log('Connect to cache is failed')
}
}
module.exports = {connectRedis}
const redis = require('redis');
const client = redis.createClient({
host: '<hostname>',
port: <port>,
password: '<password>'
});
client.on('error', err => {
console.log('Error ' + err);
});
you can read detail at here
https://docs.redis.com/latest/rs/references/client_references/client_nodejs/
Change to Version
3.1.2
remove node_modules and package-lock
open package.json
edit redis to version 3.1.2 and save it
run npm install
if you just want to install direct :
npm i redis#3.1.2
i think the issue may be due to v4+ using typescript in source code. if your server code is not typescript compatible. could be the issue .
I had a similar experience. I attributed the cause of the issue with the redis server I am using which is older than 5.0. So, perhaps you are in a similar situation.
According to the node-redis documentation,
"Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support." However, "< 5.0" is marked not supported.
install the redis client 3.1.2
just put 3.1.2 in dependencies in package.json next to redis
"dependencies" : {
"redis": "3.1.2"
}

heroku DATABASE_URL is undefined in nodejs app

Heroku site states that the DATABASE_URL is setup automatically for you. I used the command
heroku config
to confirm that the DATABASE_URL is indeed set.
However when I use the pg package command
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: true,
});
and do a console.log(process.env.DATABASE_URL), the variable reads as undefined.
The other errors that I am getting are:
UnhandledPromiseRejectionWarning: Error: The server does not support SSL connections
The complete code is:
const express = require('express');
require('dotenv').config();
const { Client } = require('pg');
const app = express();
console.log(process.env.DATABASE_URL);
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: true,
});
client.connect();
client.query('SELECT * FROM customers;', (err, res) => {
if (err) throw err;
for (let row of res.rows) {
console.log(JSON.stringify(row));
}
client.end();
});
app.get('/', (req, res) => {
res.send('Hello World')
});
app.listen(4000, () => {
console.log(`Server started on port`);
});
The code works when I use my local postgresql database, but when I try to connect to Heroku's postgres database, the above errors occur. Any suggestions?
Seems you're not crazy... This isn't working for me either, so I dug in, and it just seems... broken.
https://stackoverflow.com/a/19341505/4526479
I see DATABASE_URL defined in the heroku config vars section in the online heroku dashboard. But it's just undefined in the app.
It looks like you're running into issues connecting to the Heroku Postgres database when you run the project locally.
The DATABASE_URL environment variable specified in heroku config exists only on the Heroku server and you don't have the environment variable set locally.
Create a .env file and include your connection string like so
DATABASE_URL=...
Here you can include the connection string for the database hosted on Heroku, or your local Postgres database server. Just make sure SSL is configured correctly

Implementing Apollo Federation gateway using Express Framework

I'm currently working on a POC to implement Apollo Federation gateway in and NodeJS + express application. Up until now, I haven't really encountered any example on how to properly do it.
So far, I encounter a problem where the ApolloServer module doesn't recognize an instance of ApolloGateway from #apollo/gateway. I'm using ApolloServer instance as a wrapper of the gateway's instance as shown from the tutorial: https://www.apollographql.com/docs/apollo-server/federation/implementing/#defining-the-gateway. However, I ran into a problem when calling the server.applyMiddleWare() in my express app. I came across the example from https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-express#express
to be specific here is a snippet of the error log:
$ node --use_strict ./bin/www
/Users/evanlee/dev/federation-gateway/node_modules/loglevel-debug/index.js:32
target[k] = attr.bind ? attr.bind(k) : attr;
^
TypeError: Cannot assign to read only property 'name' of function 'function() {
return log.debug.apply(this, arguments);
}'
at /Users/evanlee/dev/federation-gateway/node_modules/loglevel-debug/index.js:32:15
at Array.forEach (<anonymous>)
at composit (/Users/evanlee/dev/federation-gateway/node_modules/loglevel-debug/index.js:30:20)
at Object.loglevelDebug [as default] (/Users/evanlee/dev/federation-gateway/node_modules/loglevel-debug/index.js:201:3)
at new ApolloGateway (/Users/evanlee/dev/federation-gateway/node_modules/#apollo/gateway/dist/index.js:101:33)
at Object.<anonymous> (/Users/evanlee/dev/federation-gateway/app.js:21:12)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
error Command failed with exit code 1.
and here is how I'm trying to integrate the ApolloServer to my express app:
const { ApolloServer } = require('apollo-server');
const { ApolloGateway } = require('#apollo/gateway');
const app = express();
// Apollo Server and Gateway definition
const server = new ApolloServer({
gateway: new ApolloGateway({
debug: true,
serviceList: [
{ name: 'base-app', url: 'http://localhost:4001/graphql' },
]
}),
subscriptions: false,
});
server.applyMiddleware({ app, path: '/graphql' });
really appreciate the help!
It's working for me using latest. However, I'm not using debug: true try without?

Couldn't resolve the error coming for mongodb atlas after deploying it on heroku?

In locally the application works perfectly but when i deployed it on heroku it showing errors on heroku logs. Also data wasn't added in mongoDb database. Actually in the application i used google-oauth login so in locally it works perfectly but not in heroku. I've also whitelisted my ip on mongodb atlas but still can't figure out why this error getting.
Anybody help me plz.....
Here is my prod.js file
module.exports = {
googleClientID: process.env.GOOGLE_CLIENT_ID,
googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
mongoURI: process.env.MONGO_URI,
cookieKey: process.env.COOKIE_KEY
}
Here is my keys.js file
// Keys.js - figure out what credentials should return
if (process.env.NODE_ENV === "production") {
// So we are in prodution - return the prod set of keys
module.exports = require('./prod');
} else {
// We are developement - return the dev keys
module.exports = require('./dev');
}
Here is my index.js file
const express = require('express');
const mongoose = require('mongoose');
const passport = require('passport');
const cookieSession = require('cookie-session');
const keys = require('./config/keys');
require('./models/User');
require('./services/passport');
const app = express();
//Middleware
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [keys.cookieKey]
})
);
app.use(passport.initialize());
app.use(passport.session());
// mongoDb Connection
mongoose.connect(keys.mongoURI, {
useNewUrlParser: true
}).then(() => console.log('MongoDb Connect successfully'))
.catch(err => console.log(err));
// actual routes
require('./routes/authRoutes')(app);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server is running in ${PORT}`));
Actually i getting two different errors first was this
2019-09-02T06:28:59.760121+00:00 app[web.1]: Warning: connect.session() MemoryStore is not
2019-09-02T06:28:59.760149+00:00 app[web.1]: designed for a production environment, as it will leak
2019-09-02T06:28:59.760151+00:00 app[web.1]: memory, and will not scale past a single process.
2019-09-02T06:28:59.763577+00:00 app[web.1]:
2019-09-02T06:28:59.763581+00:00 app[web.1]: /app/node_modules/mongoose/lib/connection.js:519
2019-09-02T06:28:59.763583+00:00 app[web.1]: throw new MongooseError('The `uri` parameter to `openUri()` must be a ' +
2019-09-02T06:28:59.763585+00:00 app[web.1]: ^
2019-09-02T06:28:59.763838+00:00 app[web.1]: MongooseError: The `uri` parameter to `openUri()` must be a string, got "undefined". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.
2019-09-02T06:28:59.763842+00:00 app[web.1]: at new MongooseError (/app/node_modules/mongoose/lib/error/mongooseError.js:10:11)
2019-09-02T06:28:59.763844+00:00 app[web.1]: at NativeConnection.Connection.openUri (/app/node_modules/mongoose/lib/connection.js:519:11)
2019-09-02T06:28:59.763846+00:00 app[web.1]: at Mongoose.connect (/app/node_modules/mongoose/lib/index.js:321:15)
2019-09-02T06:28:59.763848+00:00 app[web.1]: at Object.<anonymous> (/app/index.js:24:10)
2019-09-02T06:28:59.763850+00:00 app[web.1]: at Module._compile (internal/modules/cjs/loader.js:701:30)
2019-09-02T06:28:59.763852+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
2019-09-02T06:28:59.763854+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:600:32)
And the second one is this
2019-09-02T08:49:22.115492+00:00 app[web.1]: { MongoNetworkError: failed to connect to server [productionproj-shard-00-00-qfouv.mongodb.net:27017] on first connect [MongoNetworkError: connection 5 to productionproj-shard-00-00-qfouv.mongodb.net:27017 closed]
So on...... as same as above
Here is my mongodb production url i've been added on heroku config vars
mongodb+srv://nansProdDeploy:nansProdDeploy#productionproj-qfouv.mongodb.net/test?retryWrites=true&w=majority
It's all about whitelisting the correct ip address. When we put our application on heroku we must whitelist the ip by clicking [ Allow Access From Anywhere ] button and then click ok your ip will be 0.0.0.0/0 this ip will allow to access your deployed heroku application. When you are using your application locally at that point of you have to choose [ Add Current Ip Address ] to access your application locally

why cloud funtion in node js doesnt deploy propely

here iam using a cloud functions to create users i am using a express module when i try to deploy this code it deploying to cloud funtions with message that Error : Funtions did not deploy properly
const express = require('express');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const serviceaccount = require('./ServiceAccountKey.json');
const app = express();
admin.initializeApp({
credential: admin.credential.cert(serviceaccount)
});
app.post('/',(req,res)=>{
if(req.method!== 'POST'){
res.status(400).send("what are u trying baby");
return;
}
admin.auth().createUser({
email:req.body.email,
password: req.body.pass,
}).then(function(userRecord){
res.send({'uid': userRecord.uid});
return;
}).catch(function(error){
res.send({'error': 'Try COrrect one baby'});
return;
});
return;
});
exports.register = funtions.Https.onRequest(app);
when i add this at end
module.exports = {
app
}
it showing funtion deployed but its not showing in cloud functions dashboard
what wrong am i doing here
here is the error what ima getting i cnat get whAT THE error is
⚠ functions[register(us-central1)]: Deployment error.
Function failed on loading user code. Error message: Code in file index.js can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'express'
at Function.Module._resolveFilename (module.js:476:15)
at Function.Module._load (module.js:424:25)
at Module.require (module.js:504:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/user_code/index.js:1:79)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
Functions deploy had errors with the following functions:
register
You code never uses the firebase-functions modules to declare a Cloud Function. Your functions variable is going unused. You can't just export any function an expect it to run - it has to be built by the SDK.
If you have an express app to deploy, you need to export it via an HTTP type function:
exports.app = functions.https.onRequest(app);
First, I think you need to change the endpoint of the url. Don't just put '/'. Maybe like '/user/create'.
app.post('/user/create',(req,res)=>{
if(req.method!== 'POST'){
res.status(400).send("what are u trying baby");
return;
}
admin.auth().createUser({
email:req.body.email,
password: req.body.pass,
}).then(function(userRecord){
res.send({'uid': userRecord.uid});
return;
}).catch(function(error){
res.send({'error': 'Try COrrect one baby'});
return;
});
return;
});
exports.register = funtions.Https.onRequest(app);
And in your firebase.json you should rewrite the url :
{
"functions": {
...
},
"hosting": {
"public": "public",
"rewrites": [
{
"source": "/user/create",
"function": "register"
}
]
}
}
For more explanation, you can follow this tutorial.

Resources