Realm Legacy迁移至MongoDB完成后查询用户数据始终返回不存在问题
问题引发原因
- _id字段类型不匹配:Atlas数据库中存储的User集合_id字段多为
ObjectId类型,而代码中传入查询的uid是String类型,Realm的equalTo查询要求字段类型严格匹配,类型不一致时会直接返回无匹配结果。另外如果User模型类中声明的_id字段类型和数据库实际存储类型不一致,也会触发该问题。 - 分区权限配置错误:Realm MongoDB Sync默认按分区规则控制用户可访问的数据范围,如果旧用户的User数据所在分区未给当前登录用户分配读权限,数据不会同步到本地Realm实例,本地查询自然返回空。
- 同步未完成就提前查询:用户登录成功仅代表Auth鉴权通过,后台还需要时间把Atlas端的用户数据同步到本地Realm存储,登录完成后立即执行本地查询时数据还未同步到本地,就会出现查询不到的情况。
- 模型类字段映射错误:如果User模型类的_id字段未添加
@PrimaryKey注解,或者字段名/@Field注解值和数据库中实际的_id字段名不一致,也会导致查询匹配失败。 - 查询id和存储id不匹配:如果迁移时未将旧系统的用户id和Atlas Auth返回的用户id做对应,传入查询的uid是新Auth生成的用户id,而Atlas中存储的_id是旧系统的用户id,两者不一致也会查询不到结果。
- Realm实例类型错误:如果查询所用的realm是本地独立配置的非同步实例,而非对应Sync配置的Realm实例,也无法查询到同步过来的云端数据。
修复方案
- 对齐_id字段类型
先确认Atlas中User集合的_id字段类型,如果是ObjectId,修改查询代码为:
User userModel = realm.where(User.class).equalTo("_id", new ObjectId(uid)).findFirst();
如果需要保持String类型的id,在数据迁移时将所有User集合的_id字段统一转为String类型,同时将User模型类的_id字段类型也调整为String。
2. 调整分区权限配置
登录MongoDB Realm控制台,检查User集合的分区规则和用户角色权限,确保登录用户拥有对应分区User数据的读权限,旧用户数据的分区值和登录用户的id保持一致。
3. 监听同步完成后再查询
在登录成功后先监听同步进度,等初始同步完成后再执行查询操作,示例代码如下:
app.currentUser().getSyncSession().addDownloadProgressListener(ProgressMode.INDEFINITELY, progress -> { if (progress.isTransferComplete()) { // 同步完成后再调用getUserById查询 getUserById(uid, completionUser); } });
- 修正模型类字段映射
检查User类的_id字段声明,确保配置正确:
public class User extends RealmObject { @PrimaryKey private ObjectId _id; // 类型与数据库存储类型保持一致 // 其他字段声明 }
- 对齐查询id和存储id
如果新旧系统用户id不匹配,可在迁移数据时给User集合新增auth_uid字段存储Atlas Auth返回的用户id,查询时改为匹配auth_uid字段即可。 - 确保使用同步Realm实例
查询所用的Realm实例必须是按Sync配置生成的实例,不要使用独立的本地Realm实例查询同步数据。
内容的提问来源于stack exchange,提问作者yoshiiiiiiii
相关产品推荐
相关产品推荐

