realm-js: Error: Cannot access realm that has been closed

Hello, Realm keeps throwing this error in a simple use case: Cannot access realm that has been closed The example I am using is available at the react-native-realm repo: RealmExample.js

import Realm from 'realm';

class Item {}
Item.schema = {
  name: 'Item',
  properties: {
    name:  'string',
    date: 'date',
    id: 'string'
  },
};
export default new Realm({schema: [Item]});

app.js

//My imports
export default class App extends Component<{}> {
  render() {
    return (
      <RealmProvider realm={realm}>
        <ConnectedExample />
      </RealmProvider>
    );
  }
}

ConnectedExample.js

import React, { Component } from 'react';
import {
  Text,
  ScrollView,
  TouchableOpacity,
  View,
  StyleSheet,
} from 'react-native';
import uuid from 'uuid';
import { connectRealm } from 'react-native-realm';
import ConnectedExampleItem from './ConnectedExampleItem';

const styles = StyleSheet.create({
  screen: {
    paddingTop: 20,
    paddingHorizontal: 10,
    backgroundColor: '#2a2a2a',
    flex: 1,
  },
  add: {
    height: 44,
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 10,
    backgroundColor: '#1a1a1a',
  },
  addText: {
    color: 'white',
  },
});

class ConnectedExample extends Component {

  count = 0;

  onPressAddItem = () => {
    const { realm } = this.props;
    realm.write(() => {
      realm.create('Item', {
        name: this.count.toString(),
        date: new Date(),
        id: uuid.v4(),
      });
      this.count++;
    });
  };

  render() {
    return (
      <View style={styles.screen}>
        <TouchableOpacity onPress={this.onPressAddItem} style={styles.add}>
          <Text style={styles.addText}>Add Item</Text>
        </TouchableOpacity>
        <ScrollView>
          {this.props.items.map((item) => (
            <View key={item.id}>
              <ConnectedExampleItem id={item.id} />
            </View>
          ))}
        </ScrollView>
      </View>
    );
  }
}

export default connectRealm(ConnectedExample, {
  schemas: ['Item'],
  mapToProps(results, realm) {
    return {
      realm,
      items: results.items.sorted('date') || [],
    };
  },
});

ConnectedExampleItem.js

import React, {
  Component,
  PropTypes,
} from 'react';
import {
  StyleSheet,
  TouchableOpacity,
  Text,
} from 'react-native';
import { connectRealm } from 'react-native-realm';

const styles = StyleSheet.create({
  item: {
    height: 44,
    justifyContent: 'center',
    paddingHorizontal: 10,
    marginTop: 10,
    backgroundColor: 'cyan',
  },
});

class ConnectedExampleItem extends Component {

  onPressRemoveItem = (item) => {
    const { realm } = this.props;
    realm.write(() => {
      realm.delete(item);
    });
  };

  render() {
    return (
      <TouchableOpacity
        onPress={() => this.onPressRemoveItem(this.props.item)}
        style={styles.item}
      >
        <Text>{this.props.item.name}</Text>
      </TouchableOpacity>
    );
  }

}

export default connectRealm(ConnectedExampleItem, {
  schemas: ['Item'],
  mapToProps(results, realm, ownProps) {
    return {
      realm,
      item: results.items.find(item => item.id === ownProps.id),
    };
  },
});

Running this example in a mint project runs fine. However, when I add Realm to my own project, I run into the Cannot access realm that has been closed (I haven’t instantiated Realm anywhere else) Also, trying the example here works fine as well.

This error is mentioned nowhere in the docs or in SO. What could be causing this? How do I fix it? Thank you.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 24 (7 by maintainers)

Most upvoted comments

+1 Same issue here.

After calling realm.close() the application keeps getting this error even after a reinstall. The realmjs example doesn’t include a usage of realm.close() but it’s used once in the RealmJS docs here:

// Initialize a Realm with Car and Person models
Realm.open({schema: [CarSchema, PersonSchema]})
    .then(realm => {

        // Add persons and their cars
        realm.write(() => {
            let john = realm.create('Person', {name: 'John', cars: []});
            john.cars.push({make: 'Honda',  model: 'Accord', miles: 1500});
            john.cars.push({make: 'Toyota', model: 'Prius',  miles: 2780});

            let joan = realm.create('Person', {name: 'Joan', cars: []});
            joan.cars.push({make: 'Skoda', model: 'Octavia', miles: 1120});
            joan.cars.push({make: 'Ford',  model: 'Fiesta',  miles: 95});
            joan.cars.push({make: 'VW',    model: 'Golf',    miles: 1270});

            let jill = realm.create('Person', {name: 'Jill', cars: []});

            let jack = realm.create('Person', {name: 'Jack', cars: []});
            jack.cars.push({make: 'Porche', model: '911',    miles: 965});
        });

        // Find car owners
        let carOwners = realm.objects('Person').filtered('cars.@size > 0');
        console.log('Car owners')
        for (let p of carOwners) {
            console.log(`  ${p.name}`);
        }

        // Find who has been driver longer than average
        let average = realm.objects('Car').avg('miles');
        let longerThanAverage = realm.objects('Person').filtered('cars.@sum.miles > $0', average);
        console.log(`Longer than average (${average})`)
        for (let p of longerThanAverage) {
            console.log(`  ${p.name}: ${p.cars.sum('miles')}`);
        }

        realm.close();    <========================================== **here**
});

Is using realm.close() a strict requirement to prevent memory leakage or can I continue getting by without ever using it? Also, how on earth do I open the Realm again after a realm.close() without refactoring my code for every instance to use:

Realm.open({schema: [Schema]})
  .then(realm => { ... })

Currently I am doing export default new Realm({schema: [Schema]}) and importing as realm so I do not see a way to do a Realm.open() with my imported realm instance. Whenever I attempt to either do a realm.write() or realm.beginTransaction(), I receive the same Error: Cannot access realm that has been closed. Sorry for the long post, I’ve looked everywhere for a solution and ended up here again.

@Unforgiven-wanda this is happening on the Android side? I got the same error, but only in Android.

I 'm also doing this.

const realm = new Realm({schema: [PersonSchema]});

// You can now access the realm instance.
realm.write(/* ... */);

and then i get the mmap() fail: out of memory

if i put realm.close() at end of each realm.write… it will report that realm has been close.

how do i resolve the memory issue

i never call Realm.Close() anywhere, i just got this error when running on Android, IOS work fine, can someone help me?

@kneth Thanks for taking the time to reply. I’d be more than happy to help. I previously created a separate issue requesting the example app be updated: https://github.com/realm/realm-js/issues/1320

I would think it would only take a couple of minutes for someone at Realm to just give some general guidelines. For example, create an async function to open your realm and export from your module:

//ReactExample/components/realm.js
export default const realm = async () => {
  let realm
    try {
      realm = await Realm.open({ schema, schemaVersion: 1, encryptionKey: key })
        .catch((e) => {
	  console.error(e)
	  })
      } catch (e) {
        console.error(e)
     }
  return realm
}

and then import in your other component:

import realm from './realm';

This example is incorrect but it’s just me trying to understand how it could be implemented. I don’t know how realm.close() plays into this as well. Some best practices to follow would be extremely helpful.

i got this problem in Android only, IOS work normally, dont know why

@donni106 Yes, in my case it did work better and so far I have noticed no issue. And no, you don’t need to call realm.close() at any point.

@kneth does the team at Realm plan on releasing an official way to use Realm.open with es6 modules (import/export)? There seems to be a number of different attempted solutions by users in various issues but I have yet to find one that helps me eliminate the bug I am seeing with Realm.

@Unforgiven-wanda do you know how your solution fixes the garbage collection problem?

@Progoogler do you mind sharing your end solution? Did you refactor your code to use Realm.open and realm.close every time you needed access to the realm?

@Unforgiven-wanda I think https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management explains it better than I can do 😄

The instance created by export default new Realm({schema: [Item]}); might reach a reference count of 0, and the object is deallocated (and the Realm is closed).