React Native+TypeScript配置MongoDB Realm同步遇user属性缺失问题
解决React Native中Realm同步配置的currentUser为null问题
核心问题在于你初始化currentUser的时机太早——代码执行到const { currentUser } = app;时,用户还没完成登录流程,自然拿不到有效用户实例,导致sync配置缺失合法的user属性。
下面是具体的修复方案:
方案1:正确使用@realm/react的RealmProvider传递同步配置
你之前尝试给RealmProvider传sync props但未达预期,大概率是用法有误。正确做法是确保在用户登录后,再将已登录用户传入同步配置:
// 在根组件或登录后的组件中 import { RealmProvider } from '@realm/react'; import { realmContext } from './path-to-your-realm-config'; import { app } from './path-to-your-realm-config'; // 确保已完成登录,获取到有效用户实例 const user = app.currentUser; if (!user) { // 处理未登录逻辑,比如跳转登录页 return <LoginScreen />; } return ( <RealmProvider sync={{ user, flexible: true, onError: console.error, initialSubscriptions: { update: (subs, realm) => { subs.add(realm.objects('Task')); }, rerunOnOpen: true } }} {...realmContext} > {/* 你的应用组件 */} </RealmProvider> );
同时修改Realm配置文件,移除sync部分,只保留基础配置:
// realm-config.ts import { Realm, createRealmContext } from '@realm/react'; import { Configuration } from 'realm'; import { appId } from "../atlasConfig.json"; const app = Realm.App.getApp(appId); export class Task extends Realm.Object { _id!: Realm.BSON.ObjectId; description!: string; isComplete!: boolean; createdAt!: Date; count!: number; static generate(description: string) { return { _id: new Realm.BSON.ObjectId(), description, isComplete: false, createdAt: new Date(), count: 0 }; } static schema = { name: 'Task', primaryKey: '_id', properties: { _id: 'objectId', description: 'string', isComplete: {type: 'bool', default: false}, createdAt: 'date', count: 'int?' }, }; } const config: Configuration = { schema: [Task], schemaVersion: 0, onMigration: (oldRealm: Realm, newRealm: Realm) => { if (oldRealm.schemaVersion < 1){ const oldObjects = oldRealm.objects(Task); const newObjects = newRealm.objects(Task); for(const index in oldObjects){ const oldObject = oldObjects[index]; const newObject = newObjects[index]; if(oldObject.isComplete){ newObject.count = 1010; } else { newObject.count = 2020; } } } }, }; export const realmContext = createRealmContext(config);
方案2:动态生成带同步的Realm配置(手动初始化)
如果坚持要在配置中包含sync,必须确保在用户登录后再创建配置:
// realm-config.ts import { Realm, createRealmContext } from '@realm/react'; import { ConfigurationWithSync } from 'realm'; import { appId } from "../atlasConfig.json"; const app = Realm.App.getApp(appId); export class Task extends Realm.Object { // 保持原Task类代码不变 } // 封装函数,登录后调用获取带同步的配置 export const getRealmConfigWithSync = (user: Realm.User): ConfigurationWithSync => { return { schema: [Task], schemaVersion: 0, onMigration: (oldRealm: Realm, newRealm: Realm) => { // 保持原迁移逻辑不变 }, sync: { user, flexible: true, onError: console.error, initialSubscriptions: { update: (subs, realm) => { subs.add(realm.objects('Task')); }, rerunOnOpen: true } } }; };
在登录成功后生成配置并创建上下文:
// 登录逻辑示例 const login = async () => { const credentials = Realm.Credentials.emailPassword('user@example.com', 'password'); const user = await app.logIn(credentials); // 生成带同步的配置并创建上下文 const config = getRealmConfigWithSync(user); const { RealmProvider, useRealm } = createRealmContext(config); // 后续使用该RealmProvider渲染应用 };
关键注意点
- 同步配置必须依赖已登录用户:Realm Flexible Sync需要绑定已认证的用户实例,必须在登录流程完成后再初始化带同步的Realm。
- 类型修正:当配置包含sync时,应使用
ConfigurationWithSync类型而非Configuration,避免类型错误。 - 迁移逻辑调整:你的schemaVersion为0,但迁移逻辑判断
oldRealm.schemaVersion < 1,若还未升级过schema版本,这段逻辑暂时不会执行,可根据实际需求调整schemaVersion。
内容的提问来源于stack exchange,提问作者Théo Neubeck
相关产品推荐
相关产品推荐

