Realm Modify Database While In Read Transaction

Hello, I have a project where I want to update an existing object to my Realm Database in Kotlin but I get this error: [RLM_ERR_WRONG_TRANSACTION_STATE]: Trying to modify database while in read transaction . Anyone can help me to solve it? I tried all the documentation and still nothing, What solutions do I have?

It’s generally best practice to include a short snippet of sample code in questions so we can see what you’re attempting to do - and possibly spot where it’s going wrong.

Hello, here is my code in which I call the realm database from a module:

class AuthRepositoryIMPL @Inject constructor(
    private val realm: Realm
): AuthRepository {

    override val getUsers: Flow<RealmList<User>>
        get() = realm.query<User>()
            .find()
            .asFlow()
            .map { results->
                results.list.toRealmList()
            }

    override suspend fun getCurrentUser(list: RealmList<User>, username: String): CurrentUser {
        val user = CurrentUser()
        for (i in 0..<list.size) {
            if (list[i].username == username) {
                user.id = list[i]._id.toString()
                user.username = list[i].username
                user.password = list[i].password
                break
            }
        }
        return user
    }
    override suspend fun loginIn(list: RealmList<User>, username: String,password: String): Resource<Boolean>
    =try{
        val result = mutableStateOf(false)
        for (i in 0..<list.size)
        {
            if (username==list[i].username && password==list[i].password)
            {
                result.value=true
                break
            }
        }
        Resource.Succes(result.value)
    }catch (ex: Exception){
        Resource.Failure(ex)
    }

    override suspend fun signUp(username: String, password: String): Resource<Boolean>
    =try{
        realm.write {
            val user1 = User().apply {
                this.username = username
                this.password = password
            }
            copyToRealm(user1,UpdatePolicy.ALL)
        }
        Resource.Succes(true)
    }catch (ex: Exception){
        Resource.Failure(ex)
    }

    override suspend fun updateDataAllergens(username: String, user: CurrentUser): Resource<Boolean>
    =try{
        realm.write {
            val liveUser = realm.query<User>("username == $0",username).find().first()
            liveUser.username="Mihnea22"
        }
        Resource.Succes(true)
    }catch (ex: Exception) {
        Log.d("errorAllergens", "error: ${ex.message}")
        Resource.Failure(ex)
    }
}

This is my module

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
   @Singleton
   @Provides
   fun provideAuthRepository(): AuthRepository = AuthRepositoryIMPL(
       realm = Realm.open(
           configuration = RealmConfiguration.create(
               schema = setOf(
                   User::class,
                   Allergens::class
               )
           )
       )
   )
}

Great start!

Now, when you add a breakpoint and run your code, stepping through your code line by line, examining vars and code execution along the way, where do you run into something unexpected? What var is not correct? Which line crashes?

Also, how is this var set? What’s it populated from?

My problem is in the updateDataAllergens function, that is where I get the error from

Very good. When you step through that code, line by linem, what do the passed in parameters username and user resolve to -? Is realm valid or nil?

Is this returning anything?

realm.query<User>("username == $0",username).find().first()

Troubleshooting involves stepping through the code and checking vars - for example if username is nil, it could cause a crash. Same with realm…

Hi Serban,

Looks like you’re querying the Realm (which returns frozen results) instead of the MutableRealm instance within the write transaction (which gives you the live objects). Try changing your realm.query<> to this.query<> and see if that works:

        realm.write {
            val liveUser = this.query<User>("username == $0",username).find().first() // change realm.query to this.query
            liveUser.username="Mihnea22"
        }

This is touched on the Read page, but perhaps it’s not as clear as it needs to be for new users. I’ll cut a ticket to improve the docs.

Worked! Thank you a lot!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.