I have to develop an application in which the user has a profile picture in his schema. I am using gridfs (MongoDB). how can I access the specific picture of a user? if I upload a picture it will show on every user profile how can I make it unique?
// This is my user schema I want to add a profile picture here but I don’t know how to do it?
const Joi = require('joi');
const mongoose = require('mongoose');
const config = require('config');
const User = mongoose.model('User', new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
email: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
password: {
type: String,
// required: true,
minlength: 5,
maxlength: 1024
},
isVerified: {
type: Boolean,
default: false
}
}));
//This is my post image API I am using gridfs as a middle ware in it
const uploadFiles = async (req, res) => {
try {
await upload(req, res);
console.log(req.file);
if (req.file == undefined) {
return res.send({
message: "You must select a file.",
});
}
return res.send({
message: "File has been uploaded.",
});
} catch (error) {
console.log(error);
return res.send({
message: "Error when trying upload image: ${error}",
});
}
};
//Gridfs middleware code
const util = require("util");
const multer = require("multer");
const { GridFsStorage } = require("multer-gridfs-storage");
const dbConfig = require('../config/db')
var storage = new GridFsStorage({
url: dbConfig.url + dbConfig.database,
options: { useNewUrlParser: true, useUnifiedTopology: true },
file: (req, file) => {
const match = ["image/png", "image/jpeg"];
if (match.indexOf(file.mimetype) === -1) {
const filename = `${Date.now()}-image-${file.originalname}`;
return filename;
}
return {
bucketName: dbConfig.imgBucket,
filename: `${Date.now()}-image-${file.originalname}`
};
}
});
var uploadFiles = multer({ storage: storage }).single("file");
var uploadFilesMiddleware = util.promisify(uploadFiles);
module.exports = uploadFilesMiddleware;
//Image get API request
const getListFiles = async (req, res) => {
try {
await mongoClient.connect();
const database = mongoClient.db(dbConfig.database);
const images = database.collection(`${dbConfig.imgBucket}.files`);
const cursor = images.find({});
if ((await cursor.count()) === 0) {
return res.status(404).send({
message: "No files found!",
});
}
let fileInfos = [];
await cursor.forEach((doc) => {
fileInfos.push({
name: doc.filename,
url: baseUrl + doc.filename,
});
});
return res.status(200).send(fileInfos);
} catch (error) {
return res.status(500).send({
message: error.message,
});
}
};
//Routes
router.post('/upload', uploadFiles);
router.get('/files', getListFiles)
Images are stored in the image bucket and also I can get them too but I do not know how to get them as a user-specified image.
2
Answers
Add profilePictureURL as a string type in schema.
profilePictureURL: { type: String }
Save Profile Picture to User’s Profile picture or any folder with
current date or user’s _id or any unique Value to make it unique.
For Ex. if you save your image into public/user/profile_picture
profilePictureURL = 'public/user/profile_picture/'+user._id
Retrieve that profilePictureURL and access them using
baseURL + profilePictureURL
Mongo DB generates _id to each and every obj. You can store your image URL on the User scheme and while fetching the user you can get a specific image based on the User.
You can also use Populate fields(Like Joins) on User schema where you can store image id on user and while fetching you can populate entire image object with User itself.
You need to update your schema with the references.