0

I'm trying to add to an embedded "Conversation" object within my user collection (for a chat app) in Mongo Realm. I would like to create a "default" conversation when the user account is created, such that every user should be a member of at least one conversation that they can then add others to.

The app currently updates the user collection via a trigger and function in Realm at the back end using the email / Password authentication process.

My classes are defined in Swift as follows:

@objcMembers class User: Object, ObjectKeyIdentifiable {
    dynamic var _id = UUID().uuidString
    dynamic var partition = "" // "user=_id"
    dynamic var userName = ""
    dynamic var userPreferences: UserPreferences?
    dynamic var lastSeenAt: Date?
    var teams = List<Team>()
    dynamic var presence = "Off-Line"

    var isProfileSet: Bool { !(userPreferences?.isEmpty ?? true) }
    var presenceState: Presence {
        get { return Presence(rawValue: presence) ?? .hidden }
        set { presence = newValue.asString }
    }

    override static func primaryKey() -> String? {
        return "_id"
    }

@objcMembers class Conversation: EmbeddedObject, ObjectKeyIdentifiable {
    dynamic var id = UUID().uuidString
    dynamic var displayName = ""
    dynamic var unreadCount = 0
    var members = List<Member>()
    
}

So my current thinking is that I should code it in Swift as follows which I believe should update the logged in user, but sadly can't get this quite right:

 // Open the default realm
        let realm = try! Realm()
        
        try! realm.write {
            let conversation = Conversation()
            conversation.displayName = "My Conversation"
            conversation.unreadCount = 0
        
            var user = app.currentUser
            let userID = user.id
            
            let thisUser = User(_id: userID)
            realm.add(user)
        }

Can anyone please spot where I'm going wrong in my code?

Hours spent on Google and I'm missing something really obvious! I have a fair bit of .NET experience and SQL but struggling to convert to the new world!

I'm a noob when it comes to NoSQL databases and SwiftUI and trying to find my way looking at a lot of Google examples. My example us based on the tutorial by Andrew Morgan https://developer.mongodb.com/how-to/building-a-mobile-chat-app-using-realm-new-way/

  • The question is a bit unclear; what do you mean by a *default conversation*? Theres nothing else in the question that references so.. what are you asking? Why are you giving an embedded object an id? Can you clarify? – Jay Jun 02 '21 at 18:22
  • There's no way for us to know if that `id` is needed or not. You have it there so does it have a function? Also, we still don't know what's being asked or how a *conversation* fits into the question or the code. Remember - only you know your code so questions need to be clear, specific and brief for us to be able to help. Please take a moment and review [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) for some tips on asking. – Jay Jun 02 '21 at 18:43
  • Have edited it Jay which I hope is clearer - thanks for your input – David Carney Jun 02 '21 at 21:28
  • The code is a little non-sensical at the moment, perhaps just an oversight. Your creating a conversation with `let conversation = Conversation()` but then nothing else is done with it. Also, we don't know what the Conversation model looks like either. A Teams properties are being populated `team.displayName = "My Conversation"` but there is no team object. In the Realm write, you're creating a user with a duplicate user id, which doesn't sound like a good idea. There's also a members property `var members = List()`but we don't know what that is. Can you clarify the code? – Jay Jun 02 '21 at 23:17
  • Thanks Jay apologies team should have read conversation! Pasted incorrect code in here which I’ve now corrected. List members allows other users to be added to a conversation – David Carney Jun 03 '21 at 07:10

1 Answers1

0

I am a bit unclear on the exact use case here but I think what's being asked is how to initialize an object with default values - in this case, a default conversation, which is an embedded object.

If that's not the question, let me know so I can update.

Starting with User object

class UserClass: Object {
    @objc dynamic var _id = ObjectId.generate()
    @objc dynamic var name = ""

    let conversationList = List<ConversationClass>()

    convenience init(name: String) {
        self.init()
        self.name = name

        let convo = ConversationClass()
        self.conversationList.append(convo)
    }

    override static func primaryKey() -> String? {
        return "_id"
    }
}

and the EmbeddedObject ConversationClass

class ConversationClass: EmbeddedObject {
    dynamic var displayName = "My Conversation"
    dynamic var unreadCount = 0
    var members = List<MemberClass>()
}

The objective is that when a new user is created, they have a default conversation class added to the conversationList. That's done in the convenience init

So the entire process is like this:

let realm = Realm()
let aUser = UserClass(name: "Leroy")
try! realm.write { 
   realm.add(aUser)
}

Will initialize a new user, set their name to Leroy. It will also initialize a ConversationClass Embedded object and add it to the conversationList.

The ConversationClass object has default values set for displayName and unread count per the question.

Jay
  • 34,438
  • 18
  • 52
  • 81