Android Realm与MongoDB同步后查询无返回结果的原因是什么?
问题根因排查与解决方法
1. 阻塞方法主线程调用异常
你在getSyncRealm中使用的waitForInitialRemoteData()是线程阻塞方法,你当前直接在Fragment onCreate(主线程)调用该方法,Android 会禁止主线程阻塞操作,要么直接抛出未捕获的线程异常,要么超时后直接返回未同步的本地空Realm实例,导致你拿到的就是空库。
解决方法:
- 将
getSyncRealm逻辑放到后台协程/子线程执行,添加异常捕获逻辑; - 去掉
waitForInitialRemoteData()配置,改用SyncSession的异步同步状态回调确认初始数据同步完成后再执行查询。
2. 变更监听器首次回调为空属正常逻辑
你添加的RealmResults变更监听器会在注册时先回调一次当前本地的查询结果,初始同步未完成时本地没有数据,就会返回空集合,后续同步完成后监听器会自动第二次回调最新的数据集,不要只判断首次回调结果。
额外检查项:确认Android端MenuItem模型类和服务端Schema完全匹配,包括字段名、字段类型、必填配置、主键设置,Kotlin 模型类注意添加@PersistedName注解适配服务端字段命名,避免数据同步后无法解析为MenuItem对象,表现为查询为空。
3. 同步状态无监控无法定位错误
你当前没有添加任何同步错误、进度监听器,同步过程中出现权限错误、Schema不匹配、网络异常你都无法感知。添加以下日志即可快速定位同步问题:
// 拿到Realm实例后添加监听 realm?.syncSession?.apply { // 监听下载进度 addDownloadProgressListener(ProgressMode.INDEFINITELY) { progress -> Log.d("RealmSync", "下载进度:${progress.transferredBytes}/${progress.totalBytes}") } // 监听同步错误 addErrorListener { _, error -> Log.e("RealmSync", "同步失败:${error.errorMessage}", error) } } // 查询前确认Realm是否真的为空 Log.d("RealmCheck", "当前Realm总数据量:${realm?.where()?.count()}")
4. 同步模式不匹配问题
如果你Atlas后台配置的是*灵活同步(Flexible Sync)*而非分区同步(Partition-Based Sync),你当前使用的SyncConfiguration.Builder分区同步构造方法完全不适用,灵活同步需要使用FlexibleSyncConfiguration构造配置,且需要先添加查询订阅才能拉取到数据,就会出现iOS端适配了灵活同步逻辑可正常拉取,Android端用分区同步逻辑查询为空的现象。
内容的提问来源于stack exchange,提问作者Owen Bennett

