Search code examples
react-nativemigrationrealmuuid

How to generate UUID in Realm DB using React Native inside migration?


I'm currently trying to change the primary key for some of my schemas. They used to have an int id field but now I want to implement UUID.

Here's my code:

export const realmParams = {
    path: 'db.realm',
    migration: (oldRealm: Realm, newRealm: Realm) => {
        if(oldRealm.schemaVersion <= 34) {
            const allFatherObjects = newRealm.objects('FATHER')
            for (const fatherObject of allFatherObjects) {
                const fatherUuid = new Realm.BSON.UUID()
                fatherObject.uuid = fatherUuid

                const allSonObjectsFromFather = newRealm.objects('SON')
                .filtered(`id_father = ${fatherObject.id_father}`)

                for (let i = 0; i < allSonObjectsFromFather.length; i++) {
                    const sonObject = allSonObjectsFromFather[i]

                    sonObject.uuid = new Realm.BSON.UUID()
                    sonObject.father_uuid = fatherUuid
                }
            }
        }
    },
    schema: [
        FatherSchema,
        SonSchema,
    ],
    schemaVersion: 35,
}

But it always returns this error:

Exception in HostFunction: Primary key property 'Son.uuid' has duplicate values after migration.

I tried to log inside the migration, but nothing appears.

Also, I throw away the primary key property in both schemas to see what was passed and when looking on realm studio every field I fill in with UUID has an empty string.

I've tried to use uuid.v4 of UUID library from npm (I've already imported the getRandomValues into my index) and logging into other classes, I can confirm that it works and it shows me a UUID.

After the migration everything works fine. I am able to generate a new UUID normally and save it in the table, so I assume the problem is just inside the migration function. But I don't want to keep my schemas without a primary key.

What is the problem with generating a UUID on migration and how can I solve it?

In realm version 10, it worked fine. I got the error after updating some libs and one of them is realm. Currently in 11.9.0.


Solution

  • For some reason, the field migration from realm config object changed to onMigration. That explain why no logs could be saw, or breakpoints don't stop the code inside the function. Realm simply wasn't executing the migration. Also explain why all fields that I created was blank after removing uuid from the schemas.

    They probably forgot of update the docs.

    The new code:

    export const realmParams = {
        path: 'db.realm',
        onMigration: (oldRealm: Realm, newRealm: Realm) => {
            if(oldRealm.schemaVersion <= 34) {
                const allFatherObjects = newRealm.objects('FATHER')
                for (const fatherObject of allFatherObjects) {
                    const fatherUuid = new Realm.BSON.UUID()
                    fatherObject.uuid = fatherUuid
    
                    const allSonObjectsFromFather = newRealm.objects('SON')
                    .filtered(`id_father = ${fatherObject.id_father}`)
    
                    for (let i = 0; i < allSonObjectsFromFather.length; i++) {
                        const sonObject = allSonObjectsFromFather[i]
    
                        sonObject.uuid = new Realm.BSON.UUID()
                        sonObject.father_uuid = fatherUuid
                    }
                }
            }
        },
        schema: [
            FatherSchema,
            SonSchema,
        ],
        schemaVersion: 35,
    }