Change CustomData for Document Permissions?

Hi,

we are exploring a rather dynamic permission use-case with MongoDB realm.

The idea is, that some resources that a given user should have access to would be stored as a custom_data field (“folder”); and in document permissions we would use these as expensions.

E.g. custom data object is

{
    "_id": <ObjectId>
    "userId": "6441afd1b22e3758a2d4910c",
    "folder": "cc",
}

A document permission for an “Item” collection is:

{
  "folder": "%%user.custom_data.folder"
}

In a “static way” (i.e. custom_data is not changed) this works like a charm, if we update an “Item” document (or the rule itself).

However, if we update the custom_data document itself (e…g changing folder value) then this is not reflected via sync, only if the user logs out and logs back in within the Realm app.

According to the docs, Flexible sync should be capabile to iniate a “client reset” in such case:

“Your rules reference custom user data to determine permissions dynamically, and the value of that custom user data has changed since the last Sync session.”

What do we miss? Is “Flexible Sync” capable of this, or we need to do a user logout-login to trigger a client reset for such a use-case?

Any hint would be greatly appreciated :slight_smile:
Gabor

Hi @Gabor_Rendes,

Could you elaborate on what you mean by “this is not reflected via sync”? Ie, are you trying to sync on the custom user data collection, and you are not seeing changes to a field in that collection propagate?

What’s the question here exactly? If a client establishes a sync session with evaluated read permissions P1, and then the client disconnects, ends their session, and tries to establish a new one with evaluated read permissions P2 != P1, then the behavior is for the server to send a client reset error to the client, as you linked to in the docs.

Which SDK are you using? The SDKs provide a way to pause / resume synchronization (for example, see here for the Swift docs) – the end result of doing this is the client will terminate it’s current session and then attempt to establish a new one. If the read permissions have changed in between the two sessions, then the client should see a client reset error message in the logs. We also have a docs page on how to handle client resets here, which you may find useful.

Jonathan

Hi @Jonathan_Lee ,

thanks for the quick response.

Not exactly i try to elaborate.

Let’s say we have two Items:

Item A:

{
  "name": "a"
  "folder": "a"
}

Item B:

{
  "name": "b"
  "folder": "b"
}

Furthermore we have a user X with following custom_data:

{
 "userId": <user's id>
  "folder": "a"
}

Now if I start a Realm app, and login with user X, we’ll see Item a.
If we would add other items with “folder”: “a”, they would be synced “real-time” in the app, that’s fine so far.

However, if we change in user X’s custom_data the folder value to “b”, then our expection would be that instead of Item A, Item B would be synced. But this never happens. I have to log out & login to trigger a “client reset” and see Item B only.

I hope i could made the use-case / idea clear. Is this how Realm/Flexible sync supposed to work, or we do miss something?

(btw we use Flutter SDK, but I am not sure whether this is important/relevant)

Ah ok, I see what you’re saying now. So every time a new sync connection comes in, we lookup the custom user data for the user associated with the connecting device. As the sync session becomes established for the connection, that custom user data is used in evaluating permissions. When custom user data changes, we do not refresh the permissions mid-session; instead, the changes to custom user data will only be reflected on the next sync connection to the server. This is works as designed, although may be subject to change in the future – we have project planned to handle permission changes gracefully on the server without causing a client reset.

One way of potentially getting around this is to manually force a reconnect by pausing and then resuming synchronization; that way, on session resume (restart), permissions will be evaluated again using the updated custom user data. The Flutter SDK has docs on how to accomplish this here.

Let me know if you have any more questions,
Jonathan

Hi Jonathan!

Thank you for your detailed response, I really appreciate :slight_smile:

Yes, I can confirm that pause & resume can resolve this “refresh” issue, although it required an extra nudge:

(excerpt from Flutter code)

realm.syncSession.pause();
await currentUser!.refreshCustomData();
realm.syncSession.resume();

I am really not sure, why “refreshCustomData()” is needed but it does the trick :slight_smile:

Thank you once again, have a nice day!

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