If I used a paid (non-sleep) dyno, can I push code and ignore the uploads directory in the .gitignore file, so my uploaded files are not lost?
No. A dyno is a container (much like docker) that is built when you deploy your app. It can be started one or many times, and won't share anything. When you restart/redeploy the app, the filesystem will always be lost and reset to what it was when you deployed the app.
You need to store your uploaded files on a dedicated storage platform such as Amazon S3.
See https://devcenter.heroku.com/articles/s3-upload-node