Realm-js: Default value doesn't apply for newRealm migrations, all fields are required.

Created on 11 Jan 2018  路  19Comments  路  Source: realm/realm-js

Goals

To be able create new objects without specifying fields with default values during migration.

Expected Results

New objects created.

Actual Results

Error: http://localhost:8083/call_method net::ERR_EMPTY_RESPONSE

Steps to Reproduce

Create model with a default value and try to create new object from it during migration without using the default fields.

Code Sample

const CarSchema = {
  name: 'Car',
  properties: {
    make:  'string',
    model: 'string',
    miles: {type: 'int', default: 0},
  }
};

// will break
{
  schema: [CarSchema],
  schemaVersion: 1,
  migration: (oldRealm, newRealm) => {
    newRealm.create("CarSchema", {
      make: "lambo",
      model: "murcy"
    });
  }
}

// will succeed
{
  schema: [CarSchema],
  schemaVersion: 1,
  migration: (oldRealm, newRealm) => {
    newRealm.create("CarSchema", {
      make: "lambo",
      model: "murcy",
      miles: 0
    });
  }
}

Version of Realm and Tooling

  • Realm JS SDK Version: 2.1.1
  • Node or React Native: react-native
  • Client OS & Version: chrome 63
  • Which debugger for React Native: chrome
O-Community T-Bug

All 19 comments

@jmparsons Does it only happen during debug?

It could be a number of things including the web socket to the debug, but at the time I was trying for multiple edge cases - can it handle async? can it handle default values? etc. I dwindled each one down and async / await wouldn't work at all throwing similar errors. I don't have the code anymore for it to test right now for debug mode, but those were some of the ideas I was going through.

It is a bit of a puzzle. We run out tests with and without debug on our CI system, and we have tests for defaults: https://github.com/realm/realm-js/blob/master/tests/js/realm-tests.js#L472

Are you using Android or iOS?

Yeah I don't know what it was. I'm on iOS. The only thing I can think of since the tests look fine is that maybe I left async in the migration function. I was testing both default values and async, so that could've been it. Going to close this one out for now.

We are running into the same issue as well. com.facebook.react.JavaScript (9): EXC_BAD_ACCESS (code=1, address=0x20)

Realm version: 2.0.6
React-Native version: 0.50.3

js_object_accessor_hpp_and_slack_-_appfolio

Code snippet looks like this:

class Car extends Realm.Object {}
PartialSyncFlag.schema = {
  name: 'Car',
  primaryKey: 'id',
  properties: {
    id: 'int',
    attributeOne: { type: 'bool', default: false },
    attributeTwo: { type: 'bool', default: false },
    attributeThree: { type: 'bool', default: false },
    attributeFour: { type: 'bool', default: false },
  },
};

Migration:

// will break
function migration(oldRealm, newRealm) {
  if (oldRealm.schemaVersion < 32) {
    newRealm.create('Car', {
      id: 1,
      attributeOne: true,
      attributeTwo: true,
    }, true)
  }
}

// will succeed
function migration(oldRealm, newRealm) {
  if (oldRealm.schemaVersion < 32) {
    newRealm.create('Car', {
      id: 1,
      attributeOne: true,
      attributeTwo: true,
      attributeThree: false,
      attributeThree: false,
    }, true)
  }
}

@dotcom900825 Have you tried a recent version? Do you still see the issue?

I have just ran into this issue too.

I am running react-native 0.57.2 and realm 2.28.1

@jaltin Can you share a simple example which reproduces it?

Sure @kneth.

I struggled to get a fully working project working (I don't have enough time to spend today or the rest of the week to get it working), so I provide some pseudo code here.

Initial schema (v1)

const PersonSchema = {
    name: 'Person',
    properties: {
      name: 'string',
    },
};

Opening of db with v1 schema works fine

Realm.open({
    path: 'Main.realm',
    schema: 1,
    schemaVersion: [PersonSchema],
    migration: (oldRealm, newRealm) => {

    },
});

Modified schema (v2)

const PersonSchema = {
    name: 'Person',
    properties: {
      name: 'string',
      firstName: 'string?',
    },
};

Opening db with v2 schema and not specifying firstName gives exception

Realm.open({
    path: 'Main.realm',
    schema: 2,
    schemaVersion: [PersonSchema],
    migration: (oldRealm, newRealm) => {
        newRealm.create('Person', { name: 'Fred Bloggs' });
    },
}); 

Opening db with v2 schema and specifying firstName works

Realm.open({
    path: 'Main.realm',
    schema: 2,
    schemaVersion: [PersonSchema],
    migration: (oldRealm, newRealm) => {
        newRealm.create('Person', { name: 'Fred Bloggs', firstName: 'Fred' });
    },
}); 

I hope that is enough for you to reproduce the bug.

And I forgot to mention in my last post that this is happening on iOS 12. I haven't tested on Android.

@jaltin I have created a small test in #2424. I hope to have a fix soon.

@kneth that's great, thanks for your work!

Hey guys

Thank you @jaltin and @kneth for stumble upon this problem and reacted.

I have a RN project of 0.52 and realmjs of 2.2.4 and I stumble upon this problem as well.

It seems the default value is not persisted into default.realm it was to read it from path.

new Realm({
  path: Realm.defaultPath
})

OR

realm.open({
  path: Realm.defaultPath
})

would not have the default value set and while creating is via realm.create() API would give out an error of particular value is not set.

This breaks my linear migration setup as I only pass in the relevant Schema and updated the default.realm through new Realm({ path: path, schema: [ Person ], schemaVersion:3 }).

My current alternative approach is to pass in the migration from the beginning and forward-chain the whole schema, so that at the end of the migration, the whole Schema is being passed back to my realm connection. Which I'm afraid of performance issues might arrises in the future.

@jaltin May I know how you tackle this issue on your end? Using linear migrations. I follow this example for linear migrations.

new Realm({
  path: Realm.defaultPath
  schema:  [Person, Classes, Transaction, Tickets, ... etc] // ObjectClass extends Realm.Object
  schemaVersion: 50 // Latest schema version
})

@myself379 This issue was about the default value for properties not the default value of the path.

When creating objects, a property not marked as optional will require value if the property doesn't have a default value.

@kneth Yes, I understand, it just that I wanted to read the existing default.realm, that's why I'm only providing the path. But it does not behaves what I expected it would; it doesn't read out the default value. I need to explicitly provide the schema with default values, only then realm.create([}) doesn't crash on me.

@myself379 The schema's default values are not persisted in the Realm file. So if you open a Realm without specifying the schema in the configuration, you will lost that information.

@kneth Ah, I see. Then how should I implement my linear migration? I'm trying to standardized migration (example like Laravel migrations did).

Which means I need to redefine my latest schema and just increment schemaVersion? That wouldn't be linear migration isn't?

@myself379 Yes, you update your schema and increment the version. The version is stored in the Realm file, so when you open a file at a lower schema version, the migration is triggered.

Alright noted. Thanks @kneth

Was this page helpful?
0 / 5 - 0 ratings