One user access to few Partitions

Hello, is there a possibility on one Synced Realm to have read access to few partitions? E.g.:
In Sync I’ve selected partition key as “_partition”. In Atlas I’ve User collection with unique _partition values related to their users IDs. In addition, I’ve public collection of some skills that each user should have access to.
If I correctly understand whole Partition strategy process - when the client runs the app and create a Synced Realm with his ID as the parameter he will have access only to his collection and any other collection with different Partition value will be denied. And to get access to any other collections the client should create additional Synced Realm with additional Partition value on his App?

A synced realm can only contain objects with a single matching partition key value.

But, your app can (and often will) have multiple synced realms open at the same time (each with a different partition key value).

This post explains how you can exploit this for various partitioning strategies… Realm Partitioning Strategies | MongoDB – I think the “Combination/Hybrid” approach described in that article is probably what you’re looking for

1 Like

I’m facing the same issue and it seams a bit over complicated. (opening 2 realm based on 2 partition keys (user.id and public) is easy enough but the real problems start from there)

My example is simple: I have 2 collections: A and B. (each doc from A has a list of B)

  • I provide an initial set of A and Bs.
  • The user can use Bs from my public collection and create new As that contain public Bs.
  • the public collection will get updated by me regularly

Followup questions (about best practices):

  1. Since I need to make this mixture of elements from public and private realms, what is the recommended approach?
  • should I make a copy of all data from the public realm into the private realm? And update the documents each time I have some changes? By doing a simple math, each time I have a new user, the data will multiply so I will end up with X documents * Y users. Doesn’t look right to me.
  • should I create private documents only referencing an external key (e.g. the A document will have a list of UUIDs from the public B collection) and go to the DB each time I need to get all the data?
  • Will the upcoming “Flexible Sync” will solve this?
  1. Related to connections.

Should I keep a strong reference to the 2 realms (public and private) all the time? or should I open a new connection at each read?

For #1, a lot depends on numbers of items, sizes and how frequently they change.

The most storage efficient approach for the backend is likely to be to have the A docs contain ids of the B docs rather than embedding them. But, what happens in the mobile app? When the user accesses their A objects, the app then needs to sync all of the B objects that are referenced. You can filter on the B results, but you need to have already synced the entire partition – and so if you have large partitions, that wastes storage on the mobile device. If a user isn’t simultaneously accessing a lot of B docs (say < 10) then you could give each B doc its own partition (e.g., { partition: "public-B-7832792837582739" }) and then open just the specific partitions that the user currently needs.

If the B docs are relatively small and don’t change too often, then duplicating them within the A docs is a valid option. You can use database triggers to automate this. This is normally going to bethe most efficient option for the mobile app, but there’s extra CPU and storage overhead on the backend.

Flexible sync will certainly provide additional options (not needing to sync an entire partition).

For #2, the data doesn’t disappear from the mobile app just because the reference to the realm disappears, and so I wouldn’t worry too much about the expense of reopening realms that have already been synced. You can see exactly what’s being held locally by Realm using Realm Studio.

Thanks for the update. At #1, storing IDs (in my case document UUIDs) seams the most easy way to implement. I already need to have the public partition open so expanding Bs based on their UUID is simple enough. It shouldn’t be a problem to store all public data on device.

For #2 I’m still a bit confused. I understand that the data is already cached on the device (in my case 2 files, the public and private partitions).

Now, because each search within the app will get data from both PUBLIC/PRIVATE partitions, and each tap on app items will call the DB for details, I will have a a lot of DB Connections.

So what would you recommend:

2.1) opening both the private and public partitions and storing the ream instances and using them further for all calls.
2.2) opening the private partition on each DB “fetch”? That may happen on each item tap (imagine a search feature that returns As and each tap on an A element will fetch Bs. Based on what I see in the iOS console, I see realm sync will do a Sync: Connection + Sync: Connection: Disconnect for each call. Is that fine?

Thank for the help!

Hi @Andrei_Matei, you probably don’t need to worry too much about opening and closing the same Realm.

I build all my apps with SwiftUI where I open realms as part of opening a new views (e.g. in a chat room app, I open the realm for a chat room partition each time the user switches between rooms).

It’s not like managing connections to a “remote” database where there’s an expense to them – the Realm database is embedded within your app.

Thanks! Got it now. The amount of logs from the console made me wonder a bit. All clear now.

1 Like