I'm trying to set up notifications for an Express app using MongoDB.
I have an API endpoint where I $push
a user's id to the readBy
field in MongoDB to "mark" it as read after retrieving a user's notifications. When I make a request to this endpoint, it returns 200
and their notifications, but it isn't making any updates to the notification document in MongoDB. console.log
ing the query response in the callback gave me { acknowledged: false }
. According to the Mongoose docs, acknowledged
is a Boolean indicating everything went smoothly
, but information about what acknowledged
is and at which point in the query/write process caused it to occur was sparse. Since it didn't return any errors I couldn't find a way to troubleshoot it.
Would someone be able to shed some light on what exactly acknowledged: false
is and in what typically causes it, and why it doesn't throw an error.
Model:
const notificationSchema = new Schema({
timestamp: {
type: Date,
required: true
},
type: {
type: String,
required: true,
enum: [
'newCustomer',
'contractSigned',
'invoicePaid',
'warrantyExp',
'assignedProject'
]
},
recipients: [{
type: Schema.Types.ObjectId,
ref: 'Employee',
required: true,
}],
customer: {
type: Schema.Types.ObjectId,
ref: 'Customer',
required: true,
},
readBy: [{
type: String
}],
uuid: {
type: String,
default: uuid.v4,
immutable: true,
required: true,
},
company: {
type: Schema.Types.ObjectId, ref: 'Company'
}
});
Route:
router.get("/notification/all", withAuth, async (req, res) => {
const FOURTEEN_DAYS = new Date().setDate(new Date().getDate() 14);
try {
const { uuid, userId } = req.loggedInUser;
// Fetch notifications that have the user as a recipient.
Notification.find({
recipients: userId,
})
.populate("customer")
.exec((err, notifs) => {
if (err)
return res.status(500).json({
success: false,
message: "Error: Failed to retrieve notifications.",
});
const result = [];
const notifIds = [];
for (const notif of notifs) {
// Filter notif
result.push({
timestamp: notif.timestamp,
customer: notif.customer,
type: notif.type,
read: notif.readBy.includes(uuid),
});
// Add the user as read
notifIds.push(notif.uuid);
}
console.log(notifIds);
/* THIS RETURNS ACKNOWLEDGED: FALSE */
// Write to DB that user has read these notifications
Notification.updateMany(
{ uuid: { $in: notifIds } },
{ $push: { readBy: uuid } },
(err, resultUpdate) => {
if (err)
return res.status(500).json({
success: false,
message:
"Error: Failed to add check off notifications as read.",
});
console.log(resultUpdate);
// Delete notifications past 14 days and has been read by all recipients
Notification.deleteMany(
{
timestamp: { $gte: FOURTEEN_DAYS },
$expr: {
$eq: [{ $size: "$readBy" }, { $size: "$recipients" }],
},
},
(err) => {
if (err)
return res.status(500).json({
success: false,
message: "Error: Failed to delete old notifications.",
});
return res.status(200).json({
success: true,
notifications: result,
message: "Fetched notifications",
});
}
);
}
);
});
} catch (err) {
res.status(500).json({ success: false, message: err.toString() });
}
});
CodePudding user response:
From the docs:
The method returns a document that contains:
- A boolean acknowledged as true if the operation ran with write concern or false if write concern was disabled
- matchedCount containing the number of matched documents
- modifiedCount containing the number of modified documents
- upsertedId containing the _id for the upserted document
CodePudding user response:
So it turns out that this issue was unrelated to write concern. acknowledged: false
was being returned because the value we were trying to $push
was undefined
. So essentially Mongoose was refusing to write undefined
values, but doesn't throw an error for the input value being undefined. Putting this here in case someone else runs into this issue.