Search code examples
javascriptreact-nativerealm

Error: Realm context not found. Did you call useRealm() within a <RealmProvider/>?


I am getting the following error when using useRealm() hook:

ERROR Error: Realm context not found. Did you call useRealm() within a <RealmProvider/>?

Why am I getting this error and how to correct it?

I have followed the quickstart for React Native by Realm as described here: https://www.mongodb.com/docs/realm/sdk/react-native/quick-start/

Here is the source code.

App.jsx:

import TestView from './src/modules/sandbox/TestView';

function App() {
  return <TestView />;
}

export default App;

TestView.jsx:

import React from 'react';
import Realm from 'realm';
import { createRealmContext } from '@realm/react';
import TestComponent from './TestComponent';

// Define your object model
class Profile extends Realm.Object {
  static schema = {
    name: 'Profile',
    properties: {
      _id: 'objectId',
      name: 'string',
    },
    primaryKey: '_id',
  };
}

// Create a configuration object
const realmConfig = {
  schema: [Profile],
};

// Create a realm context
const { RealmProvider, useRealm, useObject, useQuery } = createRealmContext(realmConfig);

export default function TestView() {
  return (
    <RealmProvider>
      <TestComponent />
    </RealmProvider>
  );
}

TestComponent.jsx:

import { StyleSheet, Text, View } from 'react-native';
import React from 'react';
import { useRealm } from '@realm/react';

export default function TestComponent() {
  const realm = useRealm();

  return (
    <View style={styles.container}>
      <Text>Aloha</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'white',
  },
});

Realm and RN versions:

"realm": "^11.10.1",
"@realm/react": "^0.5.1",
"react-native": "0.71.11",

Android 13:

enter image description here

iOS 16.4:

enter image description here


Solution

  • I have opened a ticket on GitHub related to this problem ( https://github.com/realm/realm-js/issues/6013 ). Long story short: the documentation is confusing and will be updated. Here is the conversation:

    @takemeyer:

    @MinisX You must use the useQuery that was returned from createRealmContext in your application. Another option would be to omit createRealmContext and instead import the RealmProvider from @realm/react and implement it as so:

    <RealmProvider schemas={[Person]}>
    //...
    

    There is a default RealmContext already instantiated in @realm/react, so you only really need to call createRealmContext if you are creating multiple Realms. We will be updating the documentation soon to reflect this method if using Realm.

    @MinisX:

    @takameyer Thanks for the response. Based on the documentation, useQuery and useRealm hooks have different uses. Therefore I do not quite understand your first suggestion.

    • The useQuery() hook returns a collection of realm objects of a given type.

    • The useRealm() hook returns the opened realm instance.

    https://www.mongodb.com/docs/realm/sdk/react-native/use-realm-react/

    I will give a try to your second suggestion today and give a feedback. But it does also cause confusion, as documentation says:

    • Once you have wrapped your component with your RealmProvider, your component and its child components will have access to the useRealm(), useObject(), and useQuery() hooks.

    Your = something user has defined, not " instead import the RealmProvider from @realm/react ".

    @takemeyer:

    @MinisX We are reworking that documentation right now to reduce confusion. I would recommend not using createRealmContext unless you need two different Realm databases (which is not common).

    Just import RealmProvider from @realm/react and use that for your application wrapper. Then you can use useQuery, useRealm and useObject hooks directly imported from @realm/react to have global access to your realm database.

    For example, in your wrapper:

    import { RealmProvider } from "@realm/react";
     
     export default function TestView() {
       return (
         <RealmProvider schemas={[Profile]}>
           <TestComponent />
         </RealmProvider>
       );
     }
    

    And in the children:

    import { useQuery } from "@realm/react";
    
    export function ProfileList() {
      const profiles = useQuery(Profile);
      //..render the result
    }
    

    @MinisX:

    @takameyer this works, thank you for clarification!