Filters defined in Atlas are not being applied from Realm subscriptions

I’m working on a React Native project which uses Realm + Flexible Sync to sync data between Atlas and the app. The app is used by multiple companies, and a user could potentially be part of multiple companies.

I’m trying to set up a filter so that once a user logs in, the local Realm can only sync data that belongs to companies they’re part of.

When logging in, I store an array of companies in the Atuh provider custom data:

type UserProfileData = {
  id: string
  name: string
  email: string
  companies: Array<{ _id: int; name: string }>

In Atlas I also have a collection of Items:

const ItemSchema = {
  name: 'Item',
  properties: {
    _id: { type: 'objectId' },
    company_id: { type: 'int' },
    name: { type: 'string' }
  primaryKey: '_id',

To keep things simple, I’ve set up an Atlas App with anonymous authentication, as well as a filter on the Item collection to only return items that have a company_id: 1:

However, when running the app, Atlas is not applying the filter when the Realm is first initialised. I’ve created a simple app to demonstrate what it looks like in this gist, it also includes a screenshot showing that Realm is pulling through all the items, and not just the ones for company_id = 1.

Of course, I could programmatically set a filter by company_id from within my React Native code, but in terms of security setting a filter from within Atlas is a much better approach.

Hi @one_abdullah,

(Request-level) filters (the list of objects in the “filters” blob) are unsupported in flexible sync. I would recommend trying to use the document_filters field in the role configuration instead to achieve the permissions scheme that you are describing above:

"document_filters": {
   "read": { "company_id": { "$in": "%%user.custom_data.companies" } },
   "write": { "company_id": { "$in": "%%user.custom_data.companies" } }

Side note - I believe this suggestion will only work if the companies array in the custom user data is an array of _ids as opposed to an array of objects. Also, this will require adding company_id as a queryable field in the sync configuration.

Let me know if you have any other questions,

Hi Jonathan,

Thanks for your reply, I’ve tried your suggestion though it looks like it’s still not working. I’ve set the filter to company_id: 99 but it’s still returning all the items.

In the Atlas App Services rules system, write access implies read access. So in this role configuration, the "document_filters.write": true implies both read and write access at the document-level for all items. If you want to restrict both write and read access to only certain companies, you’ll need update the "document_filters.write" expression as well. For the example of "company_id": 99, it should look something like:

"document_filters": {
   "read": { "company_id": 99 },
   "write": { "company_id": 99 }

Let me know if that works for you,

Thank you very much Jonathan, that did the trick!

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