Search code examples
node.jsreactjsmongodbherokumongoose

404 Not Found when requesting after deploying to Heroku, works locally


I have been working all day on trying to deploy my MERN stack app to Heroku. So far it works perfectly fine if I run it locally. The app gets deployed on Heroku, but when I try to submit/get items from MongoDB Atlas, I get a 404 error.

I tried removing the Proxy in package.json, didn't work. I ran a build command and the file is in the correct place, still doesn't work. I'm really clueless about what could be going on..

Here is the code:

BACKEND:

index.js

const express = require('express');
const app = express();
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
app.use(cors());
app.use(express.static('build'));

app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb' }));


const uri =
  'mongodb+srv://db:[email protected]/myFirstDatabase?retryWrites=true&w=majority';

mongoose.connect(uri);

const profileSchema = new mongoose.Schema({
  ..
..
..
});
const Profile = mongoose.model('Profile', profileSchema);
module.exports = mongoose.model('Profile', profileSchema);

profileSchema.set('toJSON', {
  transform: (document, returnedObject) => {
    returnedObject.id = returnedObject._id.toString();
    delete returnedObject._id;
    delete returnedObject.__v;
  },
});




app.get('/api/profiles', (req, res) => {
  Profile.find({}).then(profiles => {
    res.json(profiles);
  });
});

app.post('/api/profiles', (request, response) => {
  const body = request.body;

  if (!body) {
    return response.status(400).json({
      error: 'content missing',
    });
  }
  const profile = new Profile({
    ...
...
...


  });

  profile.save().then(savedProfile => {
    response.json(savedProfile);
  });
});

const PORT = process.env.NODE_ENV || 3001;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

My Frontend: App.js

function App() {
  const [viewProfile, setViewProfile] = useState(false);
  const [formState, setFormState] = useState(1);
  const [prof, setProf] = useState([]);
  const handleProfile = () => {
    setViewProfile(!viewProfile);
  };
  const fetchData = async () => {
    await axios.get('/api/profiles').then(res => setProf(res.data));
  };

  useEffect(() => {
    fetchData();
  }, []);

  const addProfile = async data => {
    let img = await ImgToBase64(data.profImg);
    await axios.post('/api/profiles', {
      ...
...
...
    });
    fetchData();
    alert(`success!`);
  };
  return (
    <ChakraProvider>
...
...
...
      </ChakraProvider>
  );
}

Can I please get some help? I almost tried everything


Solution

  • Heroku offers you a node's container instead of VPS (Virtual Private Server). Inside their servers, there are more than 10k apps running on a VM. They are mapping your app port with their subdomain. for that, you have to feed port configurations to your application.

    In your code, there is process.env.NODE_ENV but in the Heroku environment, they are using process.env.PORT.

    const PORT = process.env.PORT || 3001;
    

    Also, you need to add a start script in your package.json.

    start: "node index.js"
    

    if your main file is not is the index.js, you can replace your script name with main script name