Sync Rules for publicly-accessible Documents

I’ve been racking my brain against this for some time now and I’m not sure what the best, most secure, easiest-to-develop path forward is. I would appreciate any pointers.

Here’s the situation:

  1. There is an authenticated user (A), and an unauthenticated user
  2. User A is able to open a realm with a partition value = to their user_id, sync, they have read & write access to their data.
  3. User A should be able to “share” a document in their partition, making it publicly-accessible, even to unauthenticated users
  4. User A can continue modifying the shared document. Sharing the document doesn’t affect their experience
  5. At some point, the unauthenticated user can access the data within the shared document.

Realm Sync works really well for steps 1 & 2.

However, I can’t figure out how to share a document (i.e. make it publicly accessible).

If I modify the partition value of the shared document (making it “PUBLIC” and allowing users to sync every single shared document), it would no longer sync to user A in their partition.

For step 5, I am currently using Anonymous Authentication to get an accessToken that I can use to create a GraphQL request and get the shared Document that way. This is working.

However, this only works because I have permissive read Sync Permissions, which I would like to tighten before public release of this feature.

I was hoping to define a function that provides access to this shared document only if it has been explicitly shared by user A (object.is_shared == true). However, I can’t define Document-level permissions (nor collection-level permissions).

I’m getting the impression that what I’m trying to do is unsupported by MongoDB Realm?

p.s. For clarity’s sake, the implication here is that with Sync enabled, which is required for me, I can’t define any other kind of Rule, so my only option for now is to make everything readable by everybody, unless I’m mistaken.

In writing this, it dawned on me that one approach would be to make a custom API on my own server, which calls a system function on mongo that has more permissive permissions?

Hi @Majd_Taby, one option would be to duplicate the shared documents using Realm triggers (not ideal to duplicate data I know).

Your partition key would be partition and for the PrivateDocs collection, you’d set { partition: "user=6783432" } and for the SharedDocs collection it would be set to { partition: "scope=all-the-users" }.

You would then bind functions to the sync rules to perform different checks depending on whether the partition started with user= or scope=.

If you’ve not already read it, this article discusses how to decide on and implement various partitioning strategies: https://www.mongodb.com/how-to/realm-partitioning-strategies

Yeah I’ve been trying to avoid duplicating objects. For now, it seems like trying to expose data to an unauthenticated endpoint is best done via an API that communicates directly with MongoDB Atlas, sidestepping Realm, which I will continue to use for syncing a single user’s objects.

Even if I adopt a function-based sync rule, unauthenticated users wouldn’t be able to access it, and I would have to create anonymous users for this one-off request which isn’t ideal for me

Note that you can easily implement REST APIs using Realm webhooks (so no need to add an additional platform).

The mobile app can also use the Realm SDK to read from Atlas (complete with rules to decide who can see which documents).

I tried using atlas directly, but the object I’m fetching has two references that I want to fetch in a single request. I could do this using GraphQL, but that requires an authenticated user. The same appears to be true of a webhook?

The link is broken. Should point to Realm Partitioning Strategies | MongoDB now.

1 Like

Currently working on a little World Cup Countdown app and want to use the Firehose strategy from the linked article that @Andrew_Morgan where everything is synced to everyone.

I’m assuming that I’ll still need auth, so the one that makes sense is Anonymous. Just wondering if that actually is the best practice or if there is a way to expose read-only data without a user?

I know this thread ended where @Majd_Taby asked about needing an authenticated user for webhooks as well, but it never got answered. Just trying to figure out if I can utilize Realm to quickly sync and update objects (that I would update in Atlas) as the World Cup progresses without having everyone create users?

I think anonymous auth makes sense for the read-only users and then could use email/password for the editors.