使用mongo_dart插入MongoDB文档报ObjectId非String子类型错误
问题背景
使用mongo_dart包向MongoDB插入文档时,执行insertOne方法抛出如下运行时错误:
Unhandled Exception: type 'ObjectId' is not a subtype of type 'String' of 'value'
对应执行代码如下:
var db = await Db.create(MONGO_CONN_STRING); await db.open(); var coll = db.collection('reports'); await coll.insertOne({ "username": "Tom", "action": "test", "dateTime": "today", });
问题定位
该异常不是mongo_dart包本身的缺陷,属于使用环节的配置/版本兼容问题,90%以上的同类报错由以下两个原因导致:
- 依赖版本不兼容:mongo_dart生成文档默认
_id字段依赖bson库的ObjectId类型实现,如果项目中单独引入了不匹配版本的bson,或者包管理工具拉取依赖时出现版本解析冲突,就会出现类型校验不通过的问题,把ObjectId类型错误判定为需要匹配String类型,触发类型转换异常。 - 连接串格式错误:部分旧版本mongo_dart解析不符合规范的MongoDB连接串时,会在插入文档的_id生成环节抛出同类类型错误。
修复方法
按优先级依次尝试以下操作即可解决问题:
- 重置依赖版本:删除项目根目录下的
pubspec.lock文件,在pubspec.yaml中移除单独配置的bson依赖项,将mongo_dart依赖更新为当前正式稳定版本,之后执行dart pub get(纯Dart项目)或flutter pub get(Flutter项目)重新拉取依赖,让包管理工具自动匹配版本兼容的依赖链。 - 校验连接串格式:确认
MONGO_CONN_STRING符合MongoDB官方连接串规范,本地部署实例参考格式为mongodb://localhost:27017/目标数据库名,云托管实例直接复制服务控制台提供的官方连接串即可,不要手动删减、拼接连接串参数。 - 临时规避方案:如果暂时无法调整依赖版本,可以在插入的文档中手动指定字符串类型的
_id字段,跳过驱动自动生成ObjectId的逻辑,示例代码如下:
await coll.insertOne({ "_id": DateTime.now().microsecondsSinceEpoch.toString(), "username": "Tom", "action": "test", "dateTime": "today", });
注意:手动指定字符串类型_id会丢失MongoDB原生ObjectId自带的生成时间戳、自增序列等内置属性,仅建议临时排障使用,不推荐作为长期方案。
内容的提问来源于stack exchange,提问作者TheCoder
相关产品推荐
相关产品推荐

