Adding realm objects to lists in Realm Functions

Is there an obvious method I’m missing?

I have these Read only realms for a scavenger hunt object with embedded objects of Tasks, Rules and Hunters.

I have a hunt type object in the user realm that creates the Read only Hunt and the function will update the Tasks and Rules when those are added.

However, unlike creating a trigger for when it is updated in the User realm, copying that change to the shared Read only realm, I need to create and add an embedded object to the hunt when someone joins it.

The Hunter embedded object need to be added (.append in Swift) to Hunt.hunters when someone joins.

Am I missing something obvious? How do I create a function that will add an embedded object to a list in an existing Realm object?

This seems like it should be a straight forward, typical use of Realm and functions, but nothing in the documentation or examples seem to show this functionality.

Or am I wrong and this isn’t/shouldn’t be possible?

Here is a visualization of my data. Blue is the main object, yellow are embedded objects.

Screen Shot 2021-02-14 at 12.18.33 PM

Also, a trigger observes a database change in the private Hunt object in the user partition and triggers this function (which is working for the Tasks and Rules lists):

exports = function(changeEvent) {

console.log("changeEvent.fullDocument ", JSON.stringify(changeEvent.fullDocument)); 

const mongodb = context.services.get("mongodb-atlas");
const masterHunts = mongodb.db("HuntMobDB").collection("Hunt");

var newHunt = { "_id": changeEvent.fullDocument._id + "_shared",
    "_partition": changeEvent.fullDocument.code,
    "title": changeEvent.fullDocument.title,
    "text": changeEvent.fullDocument.text,
    "scheduled": changeEvent.fullDocument.scheduled,
    "date": changeEvent.fullDocument.date,
    "photo": changeEvent.fullDocument.photo,
    "code": changeEvent.fullDocument.code,
    "maxUsers": changeEvent.fullDocument.maxUsers,
    "tasks": changeEvent.fullDocument.tasks,
    "rules": changeEvent.fullDocument.rules
};

masterHunts.updateOne({_id: changeEvent.fullDocument._id + "_shared"}, newHunt, {upsert: false});
};

Thanks.

–Kurt

I think I’m doing something similar in my chat app.

My User object/document contains a list of all the conversations that the user has been invited too.

When a user creates a new conversation, the frontend app adds the conversation details (including the list of members) to just that user’s User object. When that change is synced, a Realm trigger runs a function which adds the conversation to the User document for all of the other users that are part of that new conversation.

if (user.conversations && user.conversations.length > 0) {
    for (i = 0; i < user.conversations.length; i++) {
        let membersToAdd = [];
        if (user.conversations[i].members.length > 0) {
        for (j = 0; j < user.conversations[i].members.length; j++) {
            if (user.conversations[i].members[j].membershipStatus == "User added, but invite pending") {
            membersToAdd.push(user.conversations[i].members[j].userName);
            user.conversations[i].members[j].membershipStatus = "Membership active";
            conversationsChanged = true;
            }
        }
        } 
        if (membersToAdd.length > 0) {
        userCollection.updateMany({userName: {$in: membersToAdd}}, {$push: {conversations: user.conversations[i]}})
        .then (result => {
            console.log(`Updated ${result.modifiedCount} other User documents`);
        }, error => {
            console.log(`Failed to copy new conversation to other users: ${error}`);
        });
        }
    }
}

Details on the data/partitioning model can be found here and other details on the app here.

1 Like

Yes, thanks.

I think what you do here with membersToAdd is what I’m looking for.

I can, I think, do it like this:

User joins a hunt.
add huntlet object and add it to user.hunts in “user=user.id” partition

When that sync is changed , a Realm trigger runs a function which
creates a Hunter object in the “hunt=hunt.code” partition
and then adds that with

hunterToAdd.push(hunt.hunters)

There is a lot going on in that example with the nested for loops.

Maybe there is some room here to add some more simple examples of Realm functions? I spoke with Drew about this last week, but the lack of straight forward examples (do this in the SDK, mimic the same behavior in a realm function) has made it pretty difficult for a novice dev like myself to get going with Realm, which I know is the opposite of the desired effect.

Maybe even just more commenting in the examples would be a good place to start.

–Kurt