MongoDB Realm Flexible Sync无法同步本地数据至Atlas问题求助
Realm Sync同步问题与订阅验证解决方案
一、修复realm.subscriptions返回undefined的问题
在Flexible Sync模式下,订阅初始化是异步操作,直接在Realm.open后访问realm.subscriptions可能还未完成初始化,导致返回undefined。必须等待订阅同步完成后再操作:
const test = async () => { if (!app.currentUser) { console.error("用户未登录"); return; } console.log(app.currentUser.id); try { const realm = await Realm.open({ schema: [userSchema], // 必须传入schema,否则无法识别对象类型 sync: { user: app.currentUser, flexible: true, initialSubscriptions: { update: (subs, realm) => { subs.add(realm.objects('users')); }, } }, }); // 等待订阅同步完成 await realm.subscriptions.waitForSynchronization(); // 此时再访问subscriptions就不会返回undefined console.log("当前订阅列表:", realm.subscriptions); console.log("订阅状态:", realm.subscriptions.state); let myusers = realm.objects("users"); console.log("本地用户数据:", myusers); realm.write(() => { realm.create("users", { _id: new Realm.BSON.ObjectId(), // 必须提供主键,否则无法同步 firstname: "Masffdx", email: "tessfdft@gamils.com" }); }); // 监听订阅状态变化 realm.subscriptions.addListener((subs, state) => { console.log("订阅状态更新:", state); if (state === Realm.SubscriptionsState.Complete) { console.log("订阅已同步完成"); } }); // 关闭Realm前等待上传完成 await realm.syncSession?.waitForUpload(); realm.close(); } catch (error) { console.log("错误:", error); } }
二、确保订阅配置正确
- 必填schema参数:所有打开Realm的配置中都要包含
schema: [userSchema],否则Realm无法识别users对象类型,订阅会失效。 - 主键必须赋值:
userSchema中_id是主键,创建数据时必须生成有效的ObjectId,否则本地数据无法被标记为可同步对象。 - 匹配Atlas权限规则:在Atlas控制台中,确认当前用户的Sync权限规则允许读写
users集合,比如规则需包含对users的访问权限。
三、验证订阅有效性的方法
- 等待同步后打印订阅信息:使用
await realm.subscriptions.waitForSynchronization()后,打印realm.subscriptions可查看所有已订阅的对象集合。 - 监听订阅状态:通过
realm.subscriptions.addListener监听状态变化,关键状态包括:Realm.SubscriptionsState.Pending:订阅正在同步Realm.SubscriptionsState.Complete:订阅同步完成Realm.SubscriptionsState.Error:订阅同步出错
- 查看Atlas Sync面板:登录Atlas控制台,进入Realm应用的Sync页面,查看客户端连接数和订阅统计,确认设备已连接并发起订阅。
- 开启调试日志:初始化Realm前开启调试日志,查看同步过程中的详细错误:
Realm.setLogLevel("debug");
四、其他关键排查点
- 校验用户登录状态:所有Realm操作前必须检查
app.currentUser是否存在,避免未登录状态下的操作错误。 - 复用App实例:
anonymousLogin函数中不要重新创建Realm.App实例,复用全局的app变量,避免状态不一致。 - 移除浏览器环境依赖:
logout函数中使用的$(jQuery)和localStorage不适用于React Native,替换为React Native的状态管理或AsyncStorage。
内容的提问来源于stack exchange,提问作者Rajarshi Ghoshal
相关产品推荐
相关产品推荐

