When a user logs out of the app, I want to delete everything on realm in case a new user logs in right after. I can do that using the following code when user taps on logout button.
try realm.write {
realm.deleteAll()
}
Now, if a new user logs in (or the existing user), then i get the exception "Object has been deleted or invalidated".
How do I create new realm objects again? I'm using a realm model throughout the app called rUser that i instantiate globally in my xcode project, so I'm suspecting that's the one that needs to be reinstantiated? I just don't know how. Or maybe I'm completely wrong.
Realm framework version: ?
3.1
Realm Object Server version: ?
-
Xcode version: ?
8.3
iOS/OSX version: ?
10.3.1
Dependency manager + version: ?
-
+1
Anyone at Realm care to help?
My apologies for the delay in getting back to you, @danieldelouya. Our waiting times are typically longer during the weekend since our support and engineers generally only work M-F. However, with that said, I wanted to let you know that we've received your issue and that someone will follow-up with you soon (now that we've started the week).
In the meantime, would you please provide these values:
In the CONTRIBUTING guidelines, you will find a script,
which will help determining some of these versions.
Once an object is deleted from a Realm, attempts to access it will cause an exception to be thrown (as you've already seen).
You can either delete objects by their model class instead of deleting all objects (sparing your user object from being deleted). This a straightforward solution, but only works well if you don't have many model classes.
Otherwise, you can initialize a new user object, add it to your newly-cleared Realm, and then assign that new user object to your global rUser variable. As long as you don't use any reference to the old rUser object after your Realm has been cleared, you should be fine.
Thanks @austinzheng 馃憤
I have around 10 model classes that all need to be completely deleted once the user log out to avoid any conflicts.
I'll try approach two and get back to you.
Cheers
@austinzheng Regarding the comment:
As long as you don't use any reference to the old rUser object after your Realm has been cleared, you should be fine.
Does this also apply to RLMResults?
If I have a RLMResults property for all my objects, delete all the objects, and then fetch them again from the server (effectively getting the same objects back that I just deleted) and set the new results for [MyModel allObjects] on this property, it appears as though I get the same issue as the newly created objects are still the "same" as the deleted ones?
@austinzheng
Could not get approach two to work, but since I actually only need to reset the rUser model class, approach one seems to fit better. However, how do i set all objects in rUser til nil if I'm using a primary key?
I can set all other values to nil except the primary key. Getting the exception:
'Primary key can't be changed after an object is inserted.'
Update:
I decided to empty the object in each model class like this:
try! realm.write {
let alreadySeen = realm.objects(RealmAlreadySeen.self)
realm.delete(alreadySeen)
}
Also made some changes to the logic so i wasn't depending on the primary key, and made queries based on the primary key instead of general queries.
Thanks for the help everyone! I'm gonna close this issue.
Update 2:
@austinzheng Turns out i could not it get to work
("You can either delete objects by their model class instead of deleting all objects (sparing your user object from being deleted). This a straightforward solution, but only works well if you don't have many model classes".).
How do you delete a model class if it's based on a primary key? If i do the following, and try to sign up a new user with a new primary key i still get the crash 'Object has been deleted or invalidated.'
try! realm.write {
let user = realm.objects(RealmUser.self)
realm.delete(user)
}
If i dont delete it, the next users data gets into the previous user's data based on the primary key.
I think i'd be good with some examples, because I think I've reached a point where I just confuse myself now.
Update 3:
After I took a walk and came back, i figured the easiest thing for me was to call the following when signing out:
try! realm {
realm.deleteAll()
// Now reinstantiate all global classes again.
}
I was definitely confusing myself, because this was exactly what I needed. Thanks for all the help!
Cool! If you run into further issues please file more tickets, and thank you for using Realm!
A little late to the party, but I was wondering if anyone could offer any insights/best practices.
Let's say a user logs out, and I then proceed to cleanup everything related to that user's session, included in this cleanup task is
try? Realm().safeWrite {
realm.deleteAll()
}
Let's say there is a code smell somewhere and there's a a NotificationToken still active, or maybe an instance of one of these objects is being retained by a presented controller. Usually this is predicated on some other abuse or bad practice, but are there any precautions I can take, or a different/better solution to this scenario? Should I be instead completely destroying/recreating the database? Although, that's not going to be any more resilient.
Makes me think it might be interesting to put realm.deleteAll() on a random timer while testing/developing, as it might speed up uncovering fragile implementation.
@danieldelouya , i think you should check your memory leak or Strong retain issue on your app, i was having the save issue deleting all user data on logout and then on logging another user it as crashing with "Object has been deleted or invalidated" message , after spending whole day it was the the old realm object.
try uiRealm.write {
uiRealm.deleteAll()
}
I get the same error for this condition. My use case is
uiRealm.deleteAll() to delete all the data of the user on logout.Object has been invalidated or deletedDoes anyone have any code snippet, of how it has been handled to get rid of this error?
Are there any updates on this? Or do we still have to delete every model one at a time?
Most helpful comment
Are there any updates on this? Or do we still have to delete every model one at a time?