Deleting From RealmDB - XamarinForms

Hello , I’m having problem when deleting from Realm, I’m using Xamarin Forms with ReactiveUI. Adding , Updating works fine , but Deleting not , I’m getting Realms.Exceptions.RealmInvalidObjectException: 'Attempted to access detached row' , I have a service class that have all methods for CRUD operations . There I’m creating instance of Realm object. My service class is singleton.

@Dragan_Blanusa I think you need to use .NET’s .freeze() method for this, especially for ReactiveUI. You can see a code snippet here:
https://www.mongodb.com/article/realm-database-and-frozen-objects

A more detailed example can be seen here -

Its hard to say without seeing your code but this will likely help you

What should I do with frozen object if I can’t write and subscribe to it ?? My problem is when I remove something from server side and my mobile app is in background , and goes from background to foreground , app just crash with exception I wrote .

Can you isolate a small repro case that we can use to investigate the issue? Generally what happens is that when an object is deleted, the collection containing the object emits a collection changed event that will tell the container to remove an element. Unfortunately, some binding engines will attempt to read data from the removed item prior to the removal, which then results in RealmInvalidObjectException. We have some custom logic to handle this when using Xamarin.Forms:

Essentially, what this does is provide a custom property getter that the XF binding engine uses that will return the property’s default value instead of throwing an exception, if the object is deleted. I imagine whatever framework you’re using for ReactiveUI is doing things slightly differently, which is why it doesn’t go through that piece of code. In any case, having a small repro project will allow us to explore ways to support it.

@Dragan_Blanusa You can open an issue in this repo if you are are able to provide a reproduction case:

1 Like

I just raised a feature request about this exact kind of behaviour -

It’s interesting to see that the Realm team went down the route of adding custom handling to ‘fix’ this issue for Xamarin Forms binding. To me that’s 1) Indicative of a larger issue, and 2) Doesn’t help scenarios where Xamarin Forms binding isn’t the cause (seemingly in @Dragan_Blanusa’s case, and also in scenarios I refer to in the feature request).

Realm’s behaviour of completely invalidating objects on deletion to the point where you can’t even access properties (and hence can’t call any overriden GetHashCode() or Equals() methods, for starters) makes it fundamentally incompatible with various reactive components/libraries, and also certain UI binding approaches. Can we please (optionally!) allow a more pragmatic approach that would make life much easier?

We can create a mode of operation where accessing deleted object properties returns the default value for that type and is something we’re evaluating in relation to compiled data bindings. It is unlikely we’ll freeze objects prior to the deletion in the short-medium term as that is a fairly involved task with a lot of potential to be a footgun.

That may help in the specific data binding scenario, but unfortunately doesn’t help at all for the reactive pipeline scenarios.

The workaround we have to employ currently is to duplicate all necessary properties on each Realm object, where the copied properties are [Ignored], and we try to ensure they are kept in sync with the persisted properties, and then use those duplicated properties in Equals() and GetHashCode() so that they may still be called by reactive library implementations without blowing up the whole app when an item is deleted.

It’s an ugly, imperfect hack, but I can’t see a better way to do it. I’d love to hear any suggestions!

Thanks.

Why does the reactive library need to access properties of deleted objects? If you do have a small example that highlights the issues, I’d be happy to take it for a spin and see if there’s something clever we can do to support it.