Operation `posts.find()` buffering timed out after 10000ms

Viewed 685

It works perfectly when I tried it locally. But Heroku gives this error after server deployment. Can anyone help?

{
  "message": "Operation `posts.find()` buffering timed out after 10000ms"
}

index.js

const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
require("dotenv").config();

const app = express();
const postRouter = require("./routes/post");
const port = process.env.PORT || 5000;

app.use(cors());
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));

app.get("/", (req, res) => {
  res.send("it works");
});
//mongoose connection
const URL = process.env.CONNECTDB_URL;

mongoose.connect(URL, {
  useNewUrlParser: true,
  useCreateIndex: true,
  useUnifiedTopology: true,
});
const connection = mongoose.connection;
connection.once("open", () => {
  console.log("MongoDB database connection established successfully");
});

//router

app.use("/posts", postRouter);

//listening
app.listen(port, () => {
  console.log(`Server is running on port: ${port}`);
});

controller file is here. I am trying to get all posts. Locally I haven't got any errors

const getPosts = async (req, res) => {
  try {
    const posts = await Post.find({});
    res.status(200).json(posts);
  } catch (error) {
    res.status(404).json({
      message: error.message,
    });
  }
};
2 Answers

After 1 month of research and fighting with the code I finally got a fix. I have exactly the same issue as you. The problem in my case was not in the code, but in mongoDB refusing itself. If you use MongoDB atlas to manage your database then you need to add a trusted IP to your database security options. In that case, that should be the IP of the Heroku Server.

However, there is a problem: Heroku does not provide any IP adress for your server (https://help.heroku.com/4WADH6LX/can-you-provide-me-with-the-ip-address-for-my-application), and while you can use a third party package like Zerigo DNS, a free to use option that gives your Heroku server an IP adress. Here's a link to how to set it up: https://devcenter.heroku.com/articles/zerigo_dns

I however, used a different, less secure, but easier way. When setting the whitelisted IPs (the ones that MongoDB will accept) in MongoDB Atlas, you can select an option to trust everyone, that is, every IP adress, which will include your Heroku Server.

Here are some helpful photos:

First you click on Network Access in the security tab on the left side panel. enter image description here

Then this window should open, and click add IP adress. Your own IP adress is automatically added already, that's why your localhost server worked, but Heroku server didn't. MongoDB allowed your computer's server to request data, but not Heroku's.

enter image description here

In the popup, select ALLOW ALL IPs or something like that. Then a new IP should appear under the first one. It will have an adress of 0.0.0.0/0 meaning: "any"

enter image description here

Lastly, you might want to add Heroku environment variables using the Heroku CLI. I'm not sure, but it seems that a .env file might not be enough, so add your mongoDB URL, secrets, and ports in Heroku too.

In the app overview click on settings

enter image description here

Then, on reveal config vars:

enter image description here

And just add the variables from your .env file:

enter image description here

I had a similar issue but realised I hadn't set the Config Vars for the CONNECTDB_URL variable correctly in Heroku. That could be your issue here.

Related