Realm Swift : Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to access an invalid object'

72 views Asked by At

I'm new into iOS development, I am using Mongo Realm Swift library in my SwiftUI App.

I have 2 classes WhatsNewQuiz and ImageUrlHolder.

I am downloading WhatsNewQuiz items from the server and loop through each one of them and populating a field called quizOwnerImageUrl. The value of this field is retrieved from the other class(ImageUrlHolder). So inside the loop I check if it is available in the local realm table, if not then query it from Firebase storage then persist it to the local ImageUrlHolder realm table and return the url.

Now when getting the url is return and I persist the WhatsNewQuiz item to local table.

The list of whatsNewQuiz Items are shown on screen and the crash occurs when I scroll up and down the list AND the downloadUrl is not available in the ImageUrlHolder table AND the FirebaseStorage fails to retrieve it ( because no image is available ).

Note : This crash occurs only when the Firebase Storage query returns an error!

Here is my code :

@MainActor
func downloadWhatsNewItemsAndInsertOrUpdateAtLocalDb(item: WhatsNewQuiz? = nil) {
    Task {
        do {
            let whatsNewQuizItems = try await getMyWhatsNewQuizDocs(lastAddedAt: item?.launchedAt)
            if !whatsNewQuizItems.isEmpty {

                let realm = try await Realm()

                for item in whatsNewQuizItems {

                    do {
                        let quizOwnerImageUrl = try await getThumbnailPhotoUrl("item.quizOwnerUid") // this function is written below and I am purposely entering the wrong usedId here to force FirebaseStorage to return an error
                        item.quizOwnerImageUrl = quizOwnerImageUrl
                    } catch {
                        print("Error fetching thumbnail url: \(error)")
                    }

                    //check if the item exists in the database
                    let existingItem = realm.object(ofType: WhatsNewQuiz.self, forPrimaryKey: item.id)
                    try realm.write {
                        if existingItem == nil {
                            realm.add(item)
                        } else {
                            realm.add(item, update: .modified)
                        }
                    }
                }
            }
        } catch {
            print("Error fetching new quiz items: \(error)")
        }
    }
}

@MainActor
func getThumbnailPhotoUrl(_ personUid: String) async throws -> String {
    let realm = try await Realm()
    if let imageUrlHolder = realm.object(ofType: ImageUrlHolder.self, forPrimaryKey: thumbnailContentId(personUid)) {
        return imageUrlHolder.downloadUrl
    } else {
        do {
            let storageRef = getPersonThumbnailProfilePhotoStorageRef(personUid: personUid)
            let downloadUrl = try await storageRef.downloadURL()
            let newImageUrlHolder = ImageUrlHolder(contentId: thumbnailContentId(personUid), downloadUrl: downloadUrl.absoluteString)
            try realm.write {
                realm.add(newImageUrlHolder, update: .modified)
            }
            return downloadUrl.absoluteString
        } catch {
            throw URLError(.badServerResponse)
        }
    }
}
0

There are 0 answers