'(MERN App) All API calls returning 504 (Gateway Timeout) on Heroku deploy yet working fine locally

I have built a MERN stack app which has a few different API calls. It works as expected locally however it returns 504 (Gateway Timeout) for all the API calls when deployed on Heroku. I'm on Mongo DB Atlas for database and config values been added to Heroku config vars properly with no typo errors.(Both MONGODB_URI and NODE_ENV = production) What have I done wrong?

*package

"scripts": {
    "start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
    "start:prod": "node server.js",
    "start:dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
    "client": "cd client && npm run start",
    "seed": "node scripts/seedDB.js",
    "install": "cd client && npm install",
    "build": "cd client && npm run build",
    "heroku-postbuild": "npm run build"
  },

*server

const express = require('express');
const mongoose = require('mongoose');
const cookieSession = require('cookie-session')
const passport = require('passport');
const bodyParser = require('body-parser')
const keys = require('./config/keys');
const PORT = process.env.PORT || 5000;

require('./models');
require('./services/passport');

mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/google-book-search", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true
});

const app = express();

app.use(bodyParser.json());
app.use(
  cookieSession({
    maxAge: 30 * 24 * 60 * 60 * 1000,
    keys: [keys.cookieKey]
  })
)

app.use(passport.initialize());
app.use(passport.session());

require('./routes/authRoutes.js')(app);
require('./routes/billingRoutes.js')(app);
require('./routes/apiRoutes.js')(app);

// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
  app.use(express.static("client/build"));
}

// Send every request to the React app
// Define any API routes before this runs
app.get("*", function (req, res) {
  res.sendFile(path.join(__dirname, "./client/build/index.html"));
});

app.listen(PORT, function () {
  console.log(`🌎 ==> API server now on port ${PORT}!`);
});

*config/keys.js

if (process.env.NODE_ENV === 'production') {
    // Production
    module.exports = require('./prod');
} else {
    // Development
    module.exports = require('./dev');
}

*config/prod.js

const dotenv = require('dotenv');
dotenv.config();

module.exports = {
  googleClientID: process.env.GOOGLE_CLIENT_ID,
  googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
  mongoURI: process.env.MONGODB_URI,
  cookieKey: process.env.COOKIE_KEY,
  stripePublishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
  stripeSecretKey: process.env.STRIPE_SECRET_KEY
} 

*config/dev.js

const dotenv = require('dotenv');
dotenv.config();

module.exports = {
  googleClientID: process.env.GOOGLE_CLIENT_ID,
  googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
  mongoURI: process.env.MONGODB_URI,
  cookieKey: process.env.COOKIE_KEY,
  stripePublishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
  stripeSecretKey: process.env.STRIPE_SECRET_KEY
} 

*.env

GOOGLE_CLIENT_ID=some key
GOOGLE_CLIENT_SECRET=some key
MONGODB_URI=some key
COOKIE_KEY=some key


Solution 1:[1]

Ok. I just found out what went wrong myself and just thought I'd share with anyone who's got the same problem.

My codes were all correct except Heroku doesn't recognise .env and all the secrets saved in .env file will not be picked by Heroku which I wasn't aware of.

The solution is simply go in 'Setting' (in Heroku dashboard) -> Config Vars -> click 'Reveal Config Vars' -> add 'Key' and 'Value' of your secrets (e.g Key: GOOGLE_CLIENT_ID , Value: 'your API Key') then click 'Add'

You can add multiple key, value pairs as you need.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Min Kyung Kwon