How could I get the data of another Realm?

About

I’m developing an ios App with Realm Cloud(Realm Platform). I create Common Realm to which all end user have access, and Private Realm where personal data of each end user are saved.
In my App, user can post articles. Created articles are saved in Common Realm and all user can see them.

Goal

My App has three pages, ArticleListPage, ArticlePage and UserInfoPage.
(1)I want to show users who posted the article on ArticlePage.
(2)I want to show users a personal information of writer on ArticlePage.

ArticleListPage


ArticlePage

UserInfoPage

Question

Now I want to add “postedBy” property to “Article” object, but “User” object are saved each Private Realm.

What is the best way to create relationship between Common Realm and Private Realm? Thank you.

Model

import Foundation
import RealmSwift

// Private Realm
class User: Object {
    @objc dynamic var syncuserid     = ""
    @objc dynamic var username       = ""
    @objc dynamic var image          = ""
    @objc dynamic var email          = ""
    @objc dynamic var exp:Int        = 0
    @objc dynamic var level:Int      = 0
}

// Common Realm
class Article: Object {
    @objc dynamic var name           = ""
    @objc dynamic var body           = ""
}


To put it simply, How can end user access the data stored on another user’s Private Realm?

There’s a number of ways to approach this and it would be challenging to provide a specific answer without understanding the entire use case.

If you want data to be available to all end users, then it would be stored within that Common Realm.

Given that each user has their own Realm as well, at least some of their info will be shared so that info would also be stored in the common realm since anyone can see it at any time (based on the article it’s attached to).

So perhaps storing some user data - their screen name, their story and their favorite food would be stored on the common realm, whereas info that’s not shared is stored on their own realm.

You could also leverage Realm Permissions to provide a more granular control of control, as it can be per realm or even at the object level.

Take a look at the App Architecture guide as it provides some guidance on app design with a similar architecture as to what’s in your question.

A Common Realm for things that are required upon log in by every user - these might be

  • Minimal profile data for all users (if your users need to be able to find each other inside your app)

It’s crystal clear. Thank you.
And now I have another question. When I make DirectMessage function, which Realm should I use?
I will create DMRelation model for that function

// Common Realm? or Private Realm?
class DMRelation: Object {
    @objc dynamic var userid1 = ""
    @objc dynamic var userid2 = ""
    let chats = LinkingObjects(fromType: Message.self, property: "dmrelation")
}

class Message: Object {
    @objc dynamic var relatedChatroom: DMRelation?
    @objc dynamic var userid = ""
    @objc dynamic var body   = ""
    @objc dynamic var image  = ""
}

but I feel that each end user has relation data of all users is so inappropriate and inefficient.

It’s generally best practice to ask separate questions in separate posts so the thread doesn’t get too long and convoluted.

We don’t know what a DirectMessage function is, what the purpose is or the use case. Maybe you would have a Messages Realm where messages are stored?

I got it. I’ll be careful from now on.


DirectMessage function is real-time chat function like this


Using this, users can communicate with each other in my app.
I created DMRelation class to connect two users, and also created Message class to save chat log.
It seems a little bit inefficient to store DMRelation object of all user in Common Realm, but storing in Private Realm will be also inefficiently. Because I’m new to Realm, I don’t know what to do.

@Shi_Miya So one thought I’ve had about implementing this is -

A common realm which includes a list of all Articles. The ArticlesList View would contain a model of all Articles which has some denormalized data about the User, for instance their display name and description.

Then a user would click on an article which would navigate to a view just for that article (and bound to a query just for that Article id) - no need to modify the data model here.

Now for the trickier bit - your UserInfo page - at this point you’ll likely want to switch to a per-user realm. The user who is requesting another user’s realm will need to request the appropriate partitionKey value in order to open that realm - once they open that realm they will have read permissions for that realm and can view the users data (or as much as you want to allow, you may want to split “private” user data into another realm. )

// Common Realm
class Article: Object {
    @objc dynamic var name           = ""
    @objc dynamic var body           = ""
//this is where you put the partitionKeyValue the user object in the per-user realm
    @objc dynamic var userRealmPartitionKeyValue           = ""
}

From here you would then open the user realm for this user by passing this field into a new realm open call. Such as (pseudocode for the sake of understanding)

let realm = try! Realm(configuration: user.configuration(partitionValue: myArticle.userRealmPartitionKeyValue!))

I hope this helps. We understand that managing different realms can become a bit of an implementation detail and we are endeavoring to fix this. It is our top priority right now to implement a flexible syncing model - a la query-based sync in the legacy realm cloud which would make this schema design much easier.

@Jay I appreciate your response here and it hasn’t gone unnoticed, but I think we should direct people away from object-level permissions for the legacy realm cloud. It was a good idea but it didn’t scale and right now per-realm/partition permissions is what we have. Stay tuned for future “flexible-sync” improvements

3 Likes

First of all, Thank you for your detail explanation. It helps me a lot.
However, I have an error while trying to open other’s per-user realm, so I’ll create another question.

If I could weigh in on this. My own sense is to partition the data base into one common realm that is readonly by everyone, and multiple private user realms that are read/write only by the logged in user and not readable by anyone else. If you make the common realm writable, you might have some scalability issues as the number of users increase. All the writing to the common realm should be done by server functions that act on behalf of each user. So essentially the super user server is the only agent updating the common realm. For that I would add an operations collection that users write in their private realms, that the server listens to, and updates the shared common realm accordingly.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.