Application Error in Heroku (H10)

I’m at a loss right now. I wrote a simple backend but cannot get it to deploy. When I try to view the page after deploying to Heroku I get an application error, even though it works locally. When I check the Heroku logs I get an H10 error. Typically with this error from what I’ve read online it should resolve when you add this:

(server.js)

app.listen(process.env.PORT || 4000, () => {
    console.log('App listening on PORT 4000')
})

and this:

(package.json)

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },

Unfortunately, in my case, these fixes have not resolved it. I have no Procfile. I was wondering what else I could try to get it to deploy. Below are the meat of my app, the server.js file and the package.json file.

server.js (whole file)

const express = require('express');
const cors = require('cors');
const bcrypt = require('bcrypt')
const config = require('config')
const { check, validationResult } = require("express-validator");
var mongoose = require('mongoose');
var connectDB = require('./config/db')
// var mongoDB = 'mongodb://127.0.0.1/one_database';
const jwt = require('jsonwebtoken');
require('./models/User')
const auth = require('./auth')
const User = require('./models/User');
const Note = require('./models/Note');
require('./config/default.json')

connectDB()

// var db = mongoose.connection;

const app = express();


app.use(cors());
app.use(express.json());
app.use(express.urlencoded());


app.get('/api/user', auth, async(req, res) => {
    try {
        const user = await (await User.findById(req.user.id)).isSelected('-password');
        res.json(user);
    }   catch (err) {
        console.error(err.message);
        res.status(500).send('Server error');
    }
});

app.post('/api/register', 
[
    check('name', 'Name is required').not().isEmpty(),
    check('email', 'Please put valid email').isEmail(),
    check('password', 'Please enter a password with 6 or more characters')
    .isLength({ min: 6 })
]
, 
async (req, res) => {
    const errors = validationResult(req);
    if(!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() })
    }

    const { name, email, password } = req.body;
    
    try {
// See if user exists
let user = await User.findOne({ email });

        if(user){
    return res.status(400).json({ errors: [{ msg: 'User already exists' }]});

}


user = new User({
    name,
    email,
    password
})

// encrypt password using bcrypt

const salt = await bcrypt.genSalt(10);

user.password = await bcrypt.hash(password, salt);

await user.save();

const payload = {
    user: {
        id: user.id
    }
}

jwt.sign(
    payload, 
    config.get('jwtSecret'),
    { expiresIn: 360000 },
    (err, token) => {
        if(err) throw err;
        res.json({ token });
    });
// return jsonwebtoken

    } catch(err){
        console.error(err.message);
        res.status(500).send('Server error');

    }

    console.log(req.body);



})

app.post('/api/login', 
[
    check('email', 'Please put valid email').isEmail(),
    check('password', 'Password is required')
    .exists()
]
, 
async (req, res) => {
    const errors = validationResult(req);
    if(!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() })
    }

    const { name, email, password } = req.body;
    
    try {
// See if user exists
let user = await User.findOne({ email });

        if(!user){
    return res.status(400).json({ errors: [{ msg: 'Invalid credentials' }]});

}

const isMatch = await bcrypt.compare(password, user.password);

if(!isMatch){
    return res.status(400)
    .json({ errors: [{ msg: 'Invalid credentials'}] })
}


const payload = {
    user: {
        id: user.id
    }
}

jwt.sign(payload, 
    config.get('jwtSecret'),
    { expiresIn: 360000 },
    (err, token) => {
        if(err) throw err;
        res.json({ token });
    });
// return jsonwebtoken

    } catch(err){
        console.error(err.message);
        res.status(500).send('Server error');

    }

    console.log(req.body);

})

app.post('/api/add_note', auth, (req, res) => {
    let note = new Note(req.body);
    note.save().then(note => {
        res.status(200).json({'note': 'Note added successfully'});
    }).catch(err => {
        res.status(400).send('Adding failed');
    });
});


app.get('/api/users', auth, (req, res) => {
    Users.find({}, function(err, users){
        Usersmap = {};

        users.forEach(function(user){
            UsersMap[user._id] = user;
        });

        res.send(UsersMap)
    })

})

app.get('/api/notes', auth, (req, res) => {
    const user = req.user.id;
    Note.find({User: user}, function(err, notes){
        let NoteMap = {};

        notes.forEach(function(note){
        NoteMap[note._id] = note;            
        });

    res.send(NoteMap);
    });
});

app.get('/api/note/:id', (req, res) => {
    let id = req.params.id;
    Note.findById(id, function(err, note) {
        res.json(note);
    });
})

app.listen(process.env.PORT || 4000, () => {
    console.log('App listening on PORT 4000')
})

package.json (whole file)

{
    "name": "myapp",
    "description": "a really cool app",
    "version": "1.0.0",
    "main": "server.js",
    "engines": {
      "node": "12.11.1"
      },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bcrypt": "^5.0.0",
    "config": "^3.3.2",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "express-validator": "^6.6.1",
    "jsonwebtoken": "^8.5.1",
    "mongoose": "^5.10.7"
  }
}

Hey there,

what happens when you add a Procfile like in the Heroku Docs?

What does the log exactly say?

Hey, I just added a Procfile in my main directory with:

web: node server.js

And it is still giving me the same error in the Heroku Log. The error is below:

at=error code=H10 desc="App crashed" method=GET path="/api/notes" host=morning-depths-65175.herokuapp.com request_id=49c40941-97bf-48a1-ac42-d863bb4d5441 fwd="96.8.168.31" dyno= connect= service= status=503 bytes= protocol=https 

It seems to work now with this code in the package.json file:

{
  "name": "notesapp",
  "description": "a really cool app",
  "version": "1.0.0",
  "main": "server.js",
  "engines": {
    "start": "node server.js",
    "node": "12.x"
  },
  "scripts": {
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bcrypt": "^5.0.0",
    "config": "^3.3.2",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "express-validator": "^6.6.1",
    "jsonwebtoken": "^8.5.1",
    "mongoose": "^5.10.7"
  }
}

Not sure what exactly did the trick!