You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中MongoDB查询报错:BsonObjectId类型不支持的解决

问题:Android中使用Realm+MongoDB获取文档时出现ObjectId类型不支持错误

报错信息:

java.lang.IllegalArgumentException: Type of the key BsonObjectId(6532afe7f695fa3e25408090) is not supported. On Android you can only use types which can be stored inside the Bundle.

相关代码

MongoDB JSON Schema

{
  "title": "Diary",
  "type": "object",
  "required": [
    "_id",
    "date",
    "description",
    "mood",
    "ownerId",
    "title"
  ],
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "date": {
      "bsonType": "date"
    },
    "description": {
      "bsonType": "string"
    },
    "image": {
      "bsonType": "array",
      "items": {
        "bsonType": "string"
      }
    },
    "mood": {
      "bsonType": "string"
    },
    "ownerId": {
      "bsonType": "string"
    },
    "title": {
      "bsonType": "string"
    }
  }
}

Diary实体类(使用kbson.ObjectId)

open class Diary : RealmObject {
    @PrimaryKey var _id: ObjectId = ObjectId.invoke()
    var ownerId: String = ""
    var mood: String = Mood.Normal.name
    var title: String = ""
    var description: String = ""
    var image: RealmList<String> = realmListOf()
    var date: RealmInstant = Instant.now().toRealmInstant()
}

RequestState定义

sealed class RequestState<out T>{
    object Idle: RequestState<Nothing>()
    object Loading: RequestState<Nothing>()
    data class Error(val error: Throwable): RequestState<Nothing>()
    data class Success<T>(val data: T): RequestState<T>()
}

typealias Diaries = RequestState<Map<LocalDate, List<Diary>>>

MongoDB配置及数据获取逻辑

object MongoDB : MongoRepository {
    private val user = App.create(APP_ID).currentUser
    private lateinit var realm: Realm

    init {
        configureMongoDB()
    }

    override fun configureMongoDB() {
        if (user != null) {
            val config = SyncConfiguration.Builder(user, setOf(Diary::class))
                .initialSubscriptions { sub ->
                    add(
                        query = sub.query<Diary>(query = "ownerId == $0", user.id),
                        name = "User's Diaries"
                    )
                }
                .log(LogLevel.ALL)
                .build()
            realm = Realm.open(config)
        }
    }

    override fun getAllDiaries(): Flow<Diaries> {
        return if (user != null) {
            try {
                realm.query<Diary>(query = "ownerId == $0", user.id)
                    .sort("date", sortOrder = Sort.DESCENDING)
                    .asFlow()
                    .map { result ->
                        RequestState.Success(
                            data = result.list.groupBy {
                                it.date.toInstant()
                                    .atZone(ZoneId.systemDefault())
                                    .toLocalDate()
                            })
                    }
            } catch (e: Exception) {
                flow { emit(RequestState.Error(e)) }
            }
        } else {
            flow { emit(RequestState.Error(Exception("User is not authenticated."))) }
        }
    }
}

曾尝试降级MongoDB相关依赖,问题未解决。


修复方案

错误根源在于LazyColumn的key参数直接使用了Diary._id(ObjectId类型),而Android要求LazyColumn的key必须是可存入Bundle的类型(如String、Int等基础类型)。

将key改为Diary._id.toHexString(),把ObjectId转换为字符串类型即可解决问题。


内容的提问来源于stack exchange,提问作者vuoncog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:22:45