Understanding partitions for PUBLIC vs private data

I’m struggling to understand a couple things about partitions and Realm Sync.

I’m currently in Development Mode. I’ve create some data using the _partition key with the value of “PUBLIC” which should be accessible by all users. Additionally I’ve created some private data using the _partition key with the user’s ID string.

  1. In order for the user to sync both their private and PUBLIC data, do I need to “asyncOpen” both Realms with the _partition key set to “user.id” and “PUBLIC” respectively?

  2. My private data contains links, or lists of PUBLIC data. If I try the above (with two realms) when I try to write private data which references the PUBLIC data I get the following error: ‘Object is already managed by another Realm. Use create instead to copy it into this Realm.’

  3. Since I’m in Development Mode my expectation is that none of this should be happening right now. All data in my DB should be sync with my user, regardless of what the partition key value is under a single Realm connection instance.

  4. Also in Development mode, I would expect that I could write new data to my DB using the same Realm connection instance, but using different values for the _partition key. For example, perhaps my user would like to write PUBLIC data, they should be able to do that under the Realm instance that was opened with the partition key being their user.id, no?

Fundamentally, my hope is that I can open a single Realm instance on the client, using the _partition key of my user and sync both the user’s private and all the PUBLIC data in the Realm. At least this is what I gather is possible from the documentation.

Can someone help me understand what I’m missing and if the above is possible?

1 Like

@Brad_R

  1. Yes

  2. Realm relationships do not work across realm boundaries. Instead use a manual reference or “foreign-key” concept. For instance, you could have a field in your private realm object that is a string which refers to the id in the PUBLIC realm - you then run that query in the public realm.

  3. Not sure what you mean here. You may need to wipe your simulator to redownload the data from the server.

  4. You can do this - you can have multiple realms on the client that each correspond to different partitionKey values. In your app code you hold a different variable references to each realm - ie. publicRealm or privateRealm

OK. I think I understand now.

#3 I meant, being able to sync different partitions with one instance, you you’ve clarified in another response.

Appreciate the response. I think I need to do some more thinking about to structure data in different partitions data cannot he access across realms.

Thanks again

Sorry to revive this thread, but I have that scenario here too. I need to sync private and public data.

However, I also need that the public and private data to have relationship between them.

Example:

// public
class Client {
     static schema = { 
           //...
           properties: {
               _id: 'string',
               name: 'string',
           }
     }
}

// private
class Attendance {
     static schema = { 
           //...
           properties: {
               _id: 'string',
               client: 'Client',
           }
     }
}

And in some cases, I need to search Attendance by Client.name:

const attendances = realm.objects('Attendance').filtered('client.name CONTAINS[c} \'Douglas\'');

If I use two realm instances, one for public and the other for private data, this is not possible.

Looking in the documentation, I found this: https://docs.mongodb.com/realm/sync/data-access-patterns/partitions/#partition-strategy

Combine Strategies

To use multiple strategies in the same app, you can use a generic partition key field name like _partition with a partition value structured like a query string. For example:

_partitionKey: "user_id=abcdefg"
_partitionKey: "team_id=1234&city='New York, NY'"

You can use functions and rule expressions to parse the string and determine whether or not a given user has access to a realm based on the combined strategy.

How to use Combine Strategies, I need to use some Realm function to filter and separate the data?

Correct, different realms/partitions cannot have links between them so what you will need to do is have foreign-key esque relationship where you store a string value of the _id of the linked to object, and then perform a filter in the other realm to get the object.

You may also look at Flexible Sync here -
https://docs.mongodb.com/realm/sdk/react-native/examples/flexible-sync/

As it was designed to solve this “multi-realm” problem that can happen with partition-based sync. With Flexible Sync all your data goes into the same Realm file so you can have links between the.

Thanks for the kick answer @Ian_Ward!

Yeah, I see the Flexible Sync, but we are avoiding to migrate from Partition to Flexible Sync for now, because this will impact many things inside our app. :smiling_face_with_tear:

Btw, what is this Combine Strategies related in the Docs, maybe a mistake tip in documentation?

As you add multiple flexible sync subscriptions - or syncing queries - they aggregate the results into a single realm and remove duplicate objects.

1 Like