Realm not closing?

Hola! I’m hoping this is the correct category?

Got an issue with Realm with React Native (v0.64.1). There is also a confusion with new Realm({...}) and Realm.open(). A good example on where to use the latter?

This post is about this error:

…already opened on the current thread with a different schema.

With React Native (RN), I rely on useEffect to load my state on screen load, a “componentDidMount-like” behaviour:


import React from 'react';
import {...} from 'react-native';

// Redux
import { useSelector, useDispatch } from 'react-redux';

import Realm from 'realm';
import { TheSchemaOne, TheSchemaTwo } from 'far-far-away-land';

[...]

useEffect(() => {
  Realm.open({
    schema: [TheSchemaOne, TheSchemaTwo],
  }).then(realm => {
   
    // Send items from database to state using Redux
    // Or, insert some items in DB?

    // The closing:
    return () => realm.close();
    // Or
    // return () => { realm.close() }
 
  });
}, []);

Example taken from here.

The above executed on, say, the “index.js” and inside the “index.js” file I have many components that perform some “realm actions”. Noticed I have closed the instance so why am I getting error when performing more operations? For example, should I copy the contents from “useEffect” into a function then call that function, I get the error. How I defined my schema?


export const TheSchemaOne = {...};


[...]

EDIT:

Funny, but this is what works:


// Inside useEffect

const realm = new Realm({
    schema: [TheSchemaOne, TheSchemaTwo],
});

// Do some queries (no inserts)

// The closing
realm.close();

I’m not happy pushing an app like this to production when I don’t know what’s the issue and I’m still confused when to to use both a/synchronously methods. And sometimes I get Access to invalidated Results objects. Not sure why the SO answer says to keep it open when the official docs says we should close? To get around that error, while closing, I have to map the array and return a cloned object.

@Sylar_Ruby I think what you’ll want to do is use Realm.open but then pass the extra parameter existingRealmFileBehavior -

  schema,
  path: getDBPath(),
  sync: {
    user: app.currentUser,
    partitionValue: new ObjectID(getCatalogId()),
    error: (error) => {
      console.log(error.name, error.message)
     },
    existingRealmFileBehavior: { type: "openImmediately" }
  }
}

See the writeup here https://github.com/realm/realm-js/issues/3739#issuecomment-840293328

Generally, we’d recommend just opening the realm once via a Singleton pattern on App Start and using a Provider to pass it around to different Child Contexts with a hook. Then on app close you can call realm.close() in your lifecycle teardown. I’m not sure of your exact use case but this design pattern is the most common - there may be other reasons you want to do this open/close in every component so its not a one size fits all.

We will be going over this and some of our other best practices in our community event here - https://live.mongodb.com/events/details/mongodb-realm-global-community-presents-realm-javascript-for-react-native-applications/

if you can join we can address this and other questions

1 Like

Thanks, @Ian_Ward. That seems to work and what also works is InteractionManager. The closing does work but I needed to wrap the open inside InteractionManager. I think I’ll take a step back and read the best practices.

EDIT:

I’ve went with using a context route and all is well.

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