[Realm React] Nested/Multiple Realm Providers?

Hello, I’m building an application where the intended behavior/cases are as such:

  • A user does not have an account and has not paid: realm with local storage
  • A user has an account but has not paid: same local storage realm
  • A user has an account and has paid: realm with sync

My misunderstanding/ignorance of Realm and React component lifecycles has made this impossible for me to implement (a lot of app crashes with realm object invalidated errors). Instead, I have almost completed an implementation of this alternative behavior:

  • An account is required (this way I escape a lot of my own confusion around the UserProvider):
<UserProvider fallback={OfflineAppThatCrashesWhenMigratingLocal/SyncedRealm}>
  • If a user has an account but has not paid: local storage realm
  • If a user has an account and has paid: realm with sync

The major issue I am facing now, however, is that any time I want to access or update a user’s payment data or metadata (customData), I need access to a synced realm. More precisely, I cannot useQuery to find the corresponding Realm Object that represents the user’s customData or payment metadata, which is important if I want to update that object. Moreover, payment requires access to sync so that I can update the Atlas backend upon user payment.

My previous setup was as such:

...userPaidState
...checkUserPaid

if (!checkUserPaid) {
  return (
    <PaymentDataRealm.RealmProvider sync={someSyncConfig}>
        {childrenToCheckPaymentAndSetCheckUserPaidAndUserPaidState}
    </PaymentDataRealm.RealmProvider>
  )
}

if (!userPaid) {
  return (
    <AppDataRealm.RealmProvider>
      <App />
    </AppDataRealm.RealmProvider>
  )
}

return (
  <AppDataRealm.RealmProvider sync={someSyncConfig}>
    <App />
  </AppDataRealm.RealmProvider>
)

This setup let me check a user’s payment data on load to determine whether to provide a synced or local realm. However, this setup does not let me update a user’s customData or payment metadata, as I cannot useQuery or access synced data from a local realm.

I’ve tried another setup, namely:

// Realms defined elsewhere
const UserMetadataRealm = createRealmContext({schema: [userMetadataSchema, paymentDataSchema]});
const AppDataRealm = createRealmContext({schema: [...appDataSchema]});

// returned JSX Elements from render function
<UserMetadataRealm.RealmProvider sync={syncConfig}>
  {
      userPaid
        ? (
            <AppDataRealm.RealmProvider sync={someSyncConfig}>
              <App />
            </AppDataRealm.RealmProvider>
        )
        : (
            <AppDataRealm.RealmProvider>
              <App />
            </AppDataRealm.RealmProvider>
        )
  }
</UserMetadataRealm.RealmProvider>

However, trying to access the Realm data, even after meticulously separating the useQuery and useRealm functions (instead using AppDataRealm.useRealm or UserMetadataRealm.useRealm), I encounter thise error:

Error: Exception in HostFunction: 
Object type 'schemaObjectInUserMetadataRealm' not found in schema.

Is it possible to use nested Realm providers like this? If not, is there a recommended solution to this problem of needing to access synced metadata while limiting the client’s main app to a local realm? (Do I need to manually write data to the local realm, and then copy that data to the synced realm? :((((( )

So I have provided all the schemas to both RealmProviders but kept the sync configurations as shown above the same. I am tentatively optimistic, as I am not running into the not found in schema error, but the functionality (of local vs synced realms) is working properly.

It seems the naive solution is to provide all schemas to all providers, which… feels iffy to me…

UPDATE:
I’ve discovered that the reverse situation now happens; the app no longer crashes when switching from a local realm to a synced realm. However, when “unsubscribing” (switching from a synced to a local realm), I encounter this issue:

Error: Exception in HostFunction: Cannot access realm that has been closed.

The stack trace suggests that the issue comes from a component that calls the UserMetadataRealm.