配置同步 Realm — React Native SDK
在此页面上
您可以配置 Realm,以在许多设备之间自动同步数据,并且每个设备都有自己的本地数据副本。
有关同步 Realm 的更多信息,包括如何在App Services App中设立同步的说明,请参阅 Atlas Device Sync概述。
有关不同 Realm 配置的更多信息,请参阅配置 Realm。
先决条件
在 React Native 应用程序中使用 Flexible Sync 配置 Realm 之前,请执行以下操作:
在后端启用 Flexible Sync。您必须在后端配置 Flexible Sync,然后才能在客户端应用程序中使用。
对客户端项目中的用户进行身份验证。
配置同步 Realm
使用 @realm/react
中的提供商配置同步 Realm。
默认情况下,Realm 在返回任何内容之前会同步服务器上的所有数据。 如果您想在后台同步数据,请阅读离线时配置同步 Realm。
要配置一个同步 Realm,请执行以下操作:
从
@realm/react
导入提供商。配置
AppProvider
。配置
UserProvider
并将其嵌套在AppProvider
中。配置
RealmProvider
进行同步并将其嵌套在UserProvider
中。您必须设置同步订阅。以下示例使用初始订阅,但您也可以在RealmProvider
子组件中设置订阅。
以下是嵌套提供程序的方式:
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperSync() { return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[YourObjectModel]} sync={{ flexible: true, initialSubscriptions: { update(subs, realm) { subs.add(realm.objects(YourObjectModel)); }, }, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
注意
基于分区的同步
本页介绍了Flexible Sync Realm。 Flexible Sync 是使用Atlas Device Sync的新应用程序的首选模式。 有关使用较旧的基于分区的同步的 Realm 的信息,请参阅基于分区的同步。
AppProvider
@realm/react
AppProvider 允许您访问 App Services App 的实例。
要设置 App 客户端,请将 App ID 字符串传递给 AppProvider
的 id
属性。用 AppProvider
将所有需要访问 App 的组件括起来。
import React from 'react'; import {AppProvider} from '@realm/react'; function AppWrapper() { return ( <View> <AppProvider id={APP_ID}> <MyApp /> </AppProvider> </View> ); }
有关 AppProvider
的更多信息,请访问“连接到 Atlas App Services”页面。
UserProvider
UserProvider可让您访问 Realm 用户。 应用程序需要UserProvider
才能使用钩子。
首先,您需要使用AppProvider
和UserProvider
配置用户身份验证。 然后,使用 useApp()
和 useUser()
钩子进行身份验证。
要设置用户身份验证,请执行以下操作:
将您想要与 App Services 一起使用的所有组件封装在
AppProvider
中。在
AppProvider
内部,使用UserProvider
包装需要经过身份验证的用户有权访问的所有组件。在
UserProvider
中,在另一个用于用户登录的组件中加入fallback
属性。如果没有经过身份验证的用户,该应用则会显示此组件。在传递给
UserProvider.fallback
属性的组件中,使用Realm.App.logIn()
对用户进行身份验证,您可以使用useApp()
钩子访问该用户。
仅当您的应用程序具有经过身份验证的用户时,UserProvider
封装的组件才会渲染。这些组件可以通过 useUser()
钩子访问已经过身份验证的用户。
import React from 'react'; import {useApp, UserProvider, AppProvider} from '@realm/react'; import {Button} from 'react-native'; function AppWrapper() { return ( <AppProvider id={APP_ID}> {/* If there is no authenticated user, the app mounts the `fallback` component. Once the user successfully authenticates, the app unmounts the component in the `UserProvider.fallback` prop (the `LogIn` component in this example). */} <UserProvider fallback={LogIn}> {/* Components with access to the user. These components only mount if there's an authenticated user.*/} <RestOfApp /> </UserProvider> </AppProvider> ); } function LogIn() { const app = useApp(); // This example uses anonymous authentication. // However, you can use any authentication provider // to log a user in with this pattern. async function logInUser() { await app.logIn(Realm.Credentials.anonymous()); } return ( <Button title='Log In' onPress={logInUser} /> ); }
您可以在用户身份验证页面找到有关 UserProvider
的详情。
RealmProvider
RealmProvider是一个向其子组件公开 Realm 的包装器。 您可以通过将属性传递给RealmProvider
来配置 Realm。
呈现RealmProvider
时,会打开 Realm。 这意味着如果呈现失败,子组件将无法访问 Realm。
要配置一个同步 Realm,请执行以下操作:
从
@realm/react
导入提供商。配置
AppProvider
。配置
UserProvider
并将其嵌套在AppProvider
中。将对象模型传递给
RealmProvider
的schema
属性。创建一个 FlexibleSyncConfiguration 对象。
将
SyncConfiguration
对象传递给sync
属性,或在行内添加对象。在
RealmProvider
子组件中设置初始订阅或创建新订阅。将其他配置对象属性作为属性添加到
RealmProvider
以进一步配置您的 Realm。
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperSync() { return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[YourObjectModel]} sync={{ flexible: true, initialSubscriptions: { update(subs, realm) { subs.add(realm.objects(YourObjectModel)); }, }, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
有关配置和使用 RealmProvider
的更多信息,请查看配置 Realm 页面。
配置选项
您可以通过设置与配置对象的属性匹配的属性来配置RealmProvider
。 您还可以设置fallback
和realmRef
属性。
realmRef
- 与
useRef
一起使用,用于向RealmProvider
以外的进程公开已配置的 Realm。这对于客户端重置回退等操作非常有用。
fallback
- 在等待 Realm 打开时呈现。局部 Realm 通常打开得足够快,因此不需要
fallback
属性。
打开特定路径上的同步 Realm
realm@11.6.0
版本中的新增功能。
使用 AppConfiguration.baseFilePath 和 Realm.BaseConfiguration.path,您可以控制 Realm 和元数据文件在客户端设备上的存储位置。
为此,请设置AppProvider.baseFilePath
。如果未设置baseFilePath
,则使用当前工作目录。您还可以设置RealmProvider.sync.path
以进行更多控制。
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperSync({customBaseFilePath}) { return ( <AppProvider id={APP_ID} baseFilePath={customBaseFilePath}> <UserProvider fallback={LogIn}> <RealmProvider path={customRealmPath} schema={[Profile]} sync={{ flexible: true, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; type AppWrapperSyncProps = { customBaseFilePath: string; }; function AppWrapperSync({customBaseFilePath}: AppWrapperSyncProps) { return ( <AppProvider id={APP_ID} baseFilePath={customBaseFilePath}> <UserProvider fallback={LogIn}> <RealmProvider path={customRealmPath} schema={[Profile]} sync={{ flexible: true, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
如果设置了baseFilePath
,则元数据始终存储在<baseFilePath>/mongodb-realm/
中。 如果未设置baseFilePath
,则元数据存储在<Realm.defaultPath>/mongodb-realm
中。
Realm 文件的确切存储位置可能会有所不同,具体取决于您设置Realm.BaseConfiguration.path 的方式:
Realm.Configuration.path
未设置,baseFilePath
已设置。您的 Realm 文件存储在baseFilePath
。Realm.Configuation.path
设置为相对路径。您的 Realm 文件的存储路径是相对于baseFilePath
而言的。Realm.Configuration.path
是绝对路径。您的 Realm 文件存储在Realm.Configuration.path
中。
在离线状态下访问同步 Realm
以下各小节介绍如何使用后台同步在离线状态下访问 Realm。 为此,请使用缓存的用户和OpenRealmBehaviorConfiguration对象。
在 RealmProvider
的同步配置中,将可选的 newRealmFileBehavior
和 existingRealmFileBehavior
字段设置为您的 OpenRealmBehaviorConfiguration
对象,以启用后台同步。
您可以通过后台同步或超时后立即打开 Realm。
注意
初始登录需要网络连接
当用户注册您的应用或使用客户端上的现有帐户首次登录时,客户端必须具有网络连接。通过检查是否存在已缓存的用户档案,您可以离线打开 Realm,但前提是用户之前已在线登录。
通过后台同步立即访问
您可能希望在后台同步变更,以便在同步 Realm 从服务器下载数据时向用户显示部分数据,防止用户体验受限。对于用户设备可能离线的应用程序,我们建议在后台同步变更。要在后台同步变更,请同步打开同步 Realm。
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperOfflineSync() { const realmAccessBehavior = { type: 'openImmediately', }; return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[Profile]} sync={{ flexible: true, newRealmFileBehavior: realmAccessBehavior, existingRealmFileBehavior: realmAccessBehavior, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperOfflineSync() { const realmAccessBehavior: Realm.OpenRealmBehaviorConfiguration = { type: Realm.OpenRealmBehaviorType.OpenImmediately, }; return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[Profile]} sync={{ flexible: true, newRealmFileBehavior: realmAccessBehavior, existingRealmFileBehavior: realmAccessBehavior, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
后台同步超时后访问
如果您想要同步数据,但所处环境不确定用户是否有 Internet 连接,请指定timeOut
。 当出现以下任一情况时,此功能会自动打开 Realm:
超时时间已过。
Realm 已完全下载。
如果 Realm 在超时之前未完成下载,则将在后台继续进行初始同步。
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperTimeoutSync() { const realmAccessBehavior = { type: 'downloadBeforeOpen', timeOutBehavior: 'openLocalRealm', timeOut: 1000, }; return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[Profile]} sync={{ flexible: true, newRealmFileBehavior: realmAccessBehavior, existingRealmFileBehavior: realmAccessBehavior, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperTimeoutSync() { const realmAccessBehavior: Realm.OpenRealmBehaviorConfiguration = { type: 'downloadBeforeOpen', timeOutBehavior: 'openLocalRealm', timeOut: 1000, }; return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[Profile]} sync={{ flexible: true, newRealmFileBehavior: realmAccessBehavior, existingRealmFileBehavior: realmAccessBehavior, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
@realm/react 提供程序和钩子
@realm/react
具有上下文提供程序和钩子,可简化同步 Realm 及其数据的使用。 请参阅每个提供商的页面,了解它们及其钩子。