React-Native Realm DB调试模式插入报错:_id需为uuid类型(发布模式正常)
React Native Realm DB调试模式UUID主键插入异常解决
问题现象
- 调试模式(Metro/VSCode调试器)下插入带UUID主键的
CreditCard对象时,抛出类型错误:
EconomeApp ERROR Log Start Fri Aug 26 2022 17:41:44 GMT+0300 (Israel Daylight Time) Realm write ERROR: Error: CreditCard._id must be of type 'uuid', got 'object' ([object Object]) stack: create@[native code] anonymous@[native code] write@[native code] EconomeApp ERROR Log End
- 发布模式下插入操作完全正常,日志显示对象创建成功:
LOG Running "EconomeApp" with {"rootTag":61} LOG EconomeApp Log Start Fri Aug 26 2022 17:47:25 GMT+0300 (IDT) created one card: d6ce1d14-0dc0-43db-8b6b-c4f04f85aa41 EconomeApp Log End LOG EconomeApp Log Start Fri Aug 26 2022 17:47:25 GMT+0300 (IDT) Realm written successfuly EconomeApp Log End
问题原因
调试模式下,Metro会在调试器与应用之间对JS对象进行序列化/反序列化处理,导致Realm.BSON.UUID实例被转换为普通JS对象,Realm无法识别其为UUID类型,从而触发类型校验错误。发布模式下无此序列化过程,原生代码直接处理UUID实例,因此可以正常工作。
解决方案
方案1:传递UUID字符串替代UUID实例
插入时将UUID转换为字符串传入,Realm会自动解析为UUID类型:
this._writeToDB(() => { const uuid = new Realm.BSON.UUID(); const card1 = this._realmObject.create(CollectionTypes.CreditCard.schema.name, { _id: uuid.toString(), lastPaidDate: new Date(), cardLimit: new Realm.BSON.Decimal128("123.5123"), lastFourDigits: "1234", isManualPayment: false, dayCycle: 15 }); Helper.log(`created one card: ${card1._id}`); });
方案2:修改Schema默认值为函数形式
Schema中_id的默认值不要直接实例化UUID,改用延迟执行的函数,避免调试模式下提前序列化:
export class CreditCard { // ... 构造函数保持不变 static schema = { name: "CreditCard", primaryKey: '_id', properties: { _id: {type: "uuid", default: () => new Realm.BSON.UUID()}, // 改为函数延迟生成 lastpaidDate: { type: "date", default: () => new Date() }, // 日期默认值同理优化 cardLimit: { type: "decimal128", default: Defenitions.undefinedDecimalValue }, lastFourDigits: { type: "string", default: Defenitions.undefinedString }, isManualPayment: { type: "bool", default: Defenitions.defaultManualPayment }, dayCycle: { type: "int", default: Defenitions.defaultDayCycle } }, }; }
方案3:直接使用字面量对象插入
避免实例化自定义CreditCard类,直接传入符合Schema的字面量对象,减少序列化问题:
this._writeToDB(() => { // 利用Schema中_id的默认值自动生成UUID const card1 = this._realmObject.create(CollectionTypes.CreditCard.schema.name, { lastPaidDate: new Date(), cardLimit: new Realm.BSON.Decimal128("123.5123"), lastFourDigits: "1234", isManualPayment: false, dayCycle: 15 }); Helper.log(`created one card: ${card1._id}`); });
额外注意点
代码中CreditCard构造函数的参数lastPaidDate与Schema中的lastpaidDate大小写不一致,会导致该字段赋值失败,建议统一命名规则,避免潜在bug。
内容的提问来源于stack exchange,提问作者Ethan K
相关产品推荐
相关产品推荐

