MongoDB Realm is a great Firebase alternative that is backed by a “proper” database. I was missing automatic created_at and last_modified_at helpers from Django in a MongoDB project so I implemented them using triggers. Turns out it wasn’t as straightforward as I thought but still pretty simple in the end.
MongoDB Realm has very powerful triggers which are JavaScript functions that operate on a linked Atlas (a hosted MongoDB) cluster. The possibilities with these are almost limitless — you can even install your own npm packages! The only tricky part was to figure out a way to not fall into a forever loop when updating a document with a trigger that runs on every update.
AFAIK there isn’t a “this update was triggered by a trigger”-flag so you need to figure out the bail out condition manually. The following tigger function runs on insert, update and replace. It updates ‘lastModifiedAt’ field in a document to current timestamp using $currentDate operator but only if lastModifiedAt field is not updated in the changeEvent.
exports = function(changeEvent) { const docId = changeEvent.documentKey._id; const description = changeEvent.updateDescription; const insertEvent = changeEvent.operationType === "insert";
if (!docId || (!insertEvent && !description)) { return; }
if (insertEvent || !Object.keys(description.updatedFields).includes("lastModifiedAt")) { context.services .get("my-cluster-name") .db("my-db-name") .collection("my-collection-name") .updateOne( { _id: docId }, { $currentDate: {lastModifiedAt: true} } ); }};Adding automated created_at field is much simpler; just run the trigger with insert events and you’re set. (Or, you can retrieve the same data without any extra work by using ObjectId.getTimestamp. I always like to have a dedicated field for this, hence a trigger.)