Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Realm.delete is not working with class schema #2848

Closed
amereii opened this issue Apr 28, 2020 · 22 comments · Fixed by #3099
Closed

Realm.delete is not working with class schema #2848

amereii opened this issue Apr 28, 2020 · 22 comments · Fixed by #3099

Comments

@amereii
Copy link

amereii commented Apr 28, 2020

Goals

Realm.delete works on older versions , After upgrading from 3.4.1 to 5.0.3 , Realm.delete is not working with class schema

Actual Results

Argument to 'delete' must be a Realm object or a collection of Realm objects.

Steps to Reproduce

class Person {
  get fullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

Person.schema = {
  name: 'Person',
  properties: {
    firstName: 'string',
    lastName: 'string'
  }
};

Realm.open({schema: [Person]})
  .then(()=>{
realm.write(() => {
  const john = realm.create('Person', {
    firstName: 'John',
    lastName: 'Smith'
  });
  john.lastName = 'Peterson';
  realm.delete(john)
});
});

Code Sample

Version of Realm and Tooling

  • Realm JS SDK Version: 5.0.3
  • Node or React Native: 10.15.3 - 0.62.2
  • Client OS & Version: ? Windows 10 10.0.18362
  • Which debugger for React Native: None
@blagoev
Copy link
Contributor

blagoev commented Apr 29, 2020

@amereii
Thanks for reporting this. I have managed to reproduce it and we will be looking into providing a fix for it. In the mean time you can do a

class Person extends Realm.Object {
}

then realm.delete should work for you. Please report back if it does not.

In the future we are planning on phasing out the support of classes not explicitly extending Realm.Object

@amereii
Copy link
Author

amereii commented May 2, 2020

@blagoev after extending from extends Realm.Object , I have the following error , When my item rendered

TypeError: Reflect.construct requires the first argument be a constructor

@Jarzka
Copy link

Jarzka commented May 6, 2020

I also get the same error

TypeError: Reflect.construct requires the first argument be a constructor
construct@[native code]
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:131712:35
TestSchema@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:131742:26
create@[native code]

It happens when calling realm.create. TheSchema also extends Realm.Object.

The code causing this in bundle.js looks like this:

  function _createSuper(Derived) {
    function isNativeReflectConstruct() {
      if (typeof Reflect === "undefined" || !Reflect.construct) return false;
      if (Reflect.construct.sham) return false;
      if (typeof Proxy === "function") return true;

      try {
        Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
        return true;
      } catch (e) {
        return false;
      }
    }

    return function () {
      var Super = (0, _getPrototypeOf2.default)(Derived),
          result;

      if (isNativeReflectConstruct()) {
        var NewTarget = (0, _getPrototypeOf2.default)(this).constructor;
        result = Reflect.construct(Super, arguments, NewTarget);
      } else {
        result = Super.apply(this, arguments);
      }

      return (0, _possibleConstructorReturn2.default)(this, result);
    };

This started to happen after I updated react-native 0.59 → 0.62.2 and Realm 2.29.2 → 5.0.4.

EDIT:

It seems that this happens even if I revert Realm back to 2.29.2, but still keep react-native 0.62.2 and some other libraries updated.

When running old react-native 0.59 and Realm 2.29.2, there is no Reflect.construct call in bundle.js

EDIT 2:

If I'm correct, the code pasted above (Reflect.construct) is not related to Realm, but is generated from Babel. However, it also did not help even if I downgraded Babel.

@Jarzka
Copy link

Jarzka commented May 15, 2020

Has anyone come up with any solution?

@bkbooth
Copy link

bkbooth commented May 19, 2020

I'm desperately needing a solution for this too. My app seems stuck in a broken state.

  • If my classes extend Realm.Object, I get Reflect.construct errors in release builds or Realm object constructor must not return another value errors in development
  • If I don't extend Realm.Object then my realm.deletes are failing

I'd be happy for temporary hacks or workarounds at this point.

@Gazzini
Copy link

Gazzini commented May 20, 2020

@bkbooth I've found a workaround for now. @blagoev mentioned this issue is specific to class-based schemas, so the workaround is to pass the schemas directly.

The change was actually pretty small for me. When I call realm.open(), I changed the config from:

{ schema: [Pool, LogEntry, ReadingEntry, TreatmentEntry], schemaVersion: 0 }

to

{ schema: [Pool.schema, LogEntry.schema, ReadingEntry.schema, TreatmentEntry.schema], schemaVersion: 0 }

So, I just appended .schema to each class in the array. This works if your schemas are defined statically 😄

@bkbooth
Copy link

bkbooth commented May 20, 2020

@Gazzini do you have instance methods on your classes? Do they still work when you only pass the schema objects to realm.open()?

If not I think what you've done is roughly the same as what I've ended up doing. I changed all of my class models to plain objects (with the schema object as a property that I'm passing to realm.open())

I had to refactor any class instance methods to functions that took the instance as the first param instead of accessing as this. Effectively meaning just static methods.

If instance methods still work with your way, well, I wish I knew that yesterday, haha. Would have saved me a bunch of time refactoring things.

@Gazzini
Copy link

Gazzini commented May 20, 2020

Ah, no instance methods for me. I keep my models dumb.

@v0lume
Copy link

v0lume commented May 25, 2020

Got the same error on RN 0.62.2 and realm 3.6.5 (didn't get this error on RN 0.61.5)
Using workaround with adding .schema solves problem.
But seems I got another error - now every query by pk (using objectForPrimaryKey) returns undefined even record with such PK exists. <-- this code works perfect before upgrading to RN 0.62 and applying workaround with .scheme

@amereii
Copy link
Author

amereii commented May 27, 2020

@blagoev One month passed, Do you have plan to fix the bug? It must be a priority
The temporary workaround needs too many refactoring, As we have two different error in

realm.create TypeError: Reflect.construct requires the first argument be a constructor
and
realm.delete Argument to 'delete' must be a Realm object or a collection of Realm objects.

@v0lume
Copy link

v0lume commented May 27, 2020

this problem may be related to RN 0.62
just tested this case using realm 3.6.5 and rn 0.62 - got the same exceptions with Reflect.construct
right now it really becomes like pain in ass, we need fix for this issue

@blagoev
Copy link
Contributor

blagoev commented May 28, 2020

we are with tight resources but I will try to investigate that.

@Jarzka
Copy link

Jarzka commented May 28, 2020

So, which one is the correct way to use Realm? Should we pass the whole class (like @amereii did) or only the schema object (like @Gazzini did) to Realm.open? The first one is indeed broken, but the later works.

@bkbooth
Copy link

bkbooth commented May 28, 2020

@Jarzka my understanding is that passing the whole class is a relatively new feature (maybe only since v5?), it seems like they're moving towards it being the preferred way to provide schema's, but in my experience it isn't production ready yet.

I refactored all of our usage of Realm away from classes to using plain objects and only passing the schema objects to Realm.open. I couldn't wait any longer, we needed to release our app.

@Jarzka
Copy link

Jarzka commented May 29, 2020

Interesting because in our app, we have passed the whole class. It worked before I tried to upgrade Realm from version 2 to 5 and RN to 0.62. However, I'm not the original developer of our app so don't really know if this is the preferred way or a mistake that has just worked.

@bkbooth
Copy link

bkbooth commented May 29, 2020

Right, I could be completely wrong in my understanding then 🤷‍♂️ I've been building a new app, we only added Realm at v5.0.3 and I've been trying to understand why the class support is in the docs and yet seems to be in a broken state for release builds.

@forkeer
Copy link

forkeer commented May 29, 2020

I have this problem too
When do you solve ?

@Jarzka
Copy link

Jarzka commented Jun 1, 2020

I was able to solve the writing issue with the workaround explained by @Gazzini. But now, when I read things from Realm, it always returns empty objects...

realm.objects('MySchema');

Returns:

{ '0': {},
  '1': {},
  '2': {},
  '3': {},
  '4': {},
  '5': {},
  '6': {},
  '7': {},
  '8': {},
  '9': {} }

I checked that MySchema contains data in the database by pulling the database out of the device and exploring it with Realm Studio. The problem also applies to all schemas.

I'm running Realm 5.0.5.

EDIT: There seems to be thread of this issue: #2763

EDIT 2: It seems that this empty object issue can be "solved" by downgrading back to 3.6.5.

@amereii
Copy link
Author

amereii commented Jul 13, 2020

@kneth @blagoev @fealebenpae take a look please!!

@mtford90
Copy link

mtford90 commented Jul 23, 2020

Found a workaround without having to drop back to dumb objects:

const collection = db.objects('schema-name').filtered(`id = $0`, id)
db.delete(collection);

This is a pretty bad bug and it was first reported 3 months ago. There's been all sorts of new versions since then with new features - does it not make sense perhaps to fix existing features before adding new features on top of them?

I don't know cpp but the issue seems to be here -

throw std::runtime_error("Argument to 'delete' must be a Realm object or a collection of Realm objects.");

@blagoev
Copy link
Contributor

blagoev commented Jul 30, 2020

We have fixed the realm.delete error. It will be included in our next release. Thanks for reporting it.

@SanjanaTailor
Copy link

SanjanaTailor commented Jun 22, 2021

Found a workaround without having to drop back to dumb objects:

const collection = db.objects('schema-name').filtered(`id = $0`, id)
db.delete(collection);

This is a pretty bad bug and it was first reported 3 months ago. There's been all sorts of new versions since then with new features - does it not make sense perhaps to fix existing features before adding new features on top of them?

I don't know cpp but the issue seems to be here -

https://github.com/realm/realm-js/blob/0a151f96d83063d96381c0c26bcb6df74158cc4c/src/js_realm.hpp#L1021hell

Hello what is id here is it primary key ?
const collection = RealmDB.realm
.objects('Student')
.filtered(ID = $105,ID);
RealmDB.realm.delete(collection);

error [ReferenceError: Can't find variable: ID ]

also I am facing an issue says error [Error: Can only delete objects within a transaction.] in RN 0.63

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants