管理同步订阅 — C++ SDK
在此页面上
Flexible Sync 使用订阅和权限来确定要在 Atlas App Services App 和客户端设备之间同步哪些数据。 在客户端中,查询订阅托管和筛选可以同步到域的 Realm 对象类型。
先决条件
要在应用程序中使用Flexible Sync,您必须:
本页示例的设置代码满足以下先决条件:
// Initialize the App, authenticate a user, and open the database auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto user = app.login(realm::App::credentials::anonymous()).get(); auto syncConfig = user.flexible_sync_configuration(); auto syncedRealm = realm::db(syncConfig);
此外,用于 Sync 的模型必须包含名为 _id
的主键属性。 有关使用主键定义模型的更多信息,请参阅指定主键。
将订阅与后端应用保持一致
客户端订阅查询必须与后端 App Services 应用程序中的 Device Sync 配置保持一致。
订阅查询可以:
查询某一类型的所有对象。
与后端应用的可查询字段匹配的类型的查询对象。
要了解有关配置可查询字段的更多信息,请参阅 App Services 文档中的可查询字段。
同步 Realm 必须具有一个或多个订阅,才能在该 Realm 中读取和写入数据。 您只能将数据写入与一个或多个订阅匹配且与用户权限匹配的 Realm。 如果您尝试将对象写入与订阅不匹配的域,或者用户无权执行写入操作,则会从服务器获得补偿写入,并且写入会还原。
托管您的订阅
在后端配置 Flexible Sync 时,您可以指定客户端应用程序可以查询哪些字段。 在客户端应用程序中, sync_subscription_set是零个或多个sync_subscription对象的列表,这些对象确定 Realm 可以存储哪些对象。
Realm C++ SDK 还具有mutable_sync_subscription_set ,可让您添加、更改和删除sync_subscription
对象。
验证订阅数量或查找特定订阅
当您的应用程序首次打开同步 Realm 时,您可能需要验证它是否具有预期数量的订阅或具有特定的订阅。
您可以通过访问Realm的subscriptions()
公共成员函数来获取此信息。 这提供了sync_subscription_set ,您可以在其中使用size()
或find()
成员函数。
// Check the subscription count CHECK(syncedRealm.subscriptions().size() == 1); // Find a specific subscription by name auto puppySubscription = *syncedRealm.subscriptions().find("puppies"); CHECK(puppySubscription.name == "puppies"); // Get information about the subscription CHECK(puppySubscription.object_class_name == "Dog"); CHECK(puppySubscription.query_string == "age < 3");
添加同步订阅
要更新订阅集,请使用subscription().updates()
函数。 这使您可以访问mutable_sync_subscription_set ,您可以在其中使用add()
函数添加新的同步订阅。
此模板需要您要同步的对象的Realm 对象类型以及订阅的字符串名称。
订阅某一类型的所有对象
您可以订阅某一类型的所有对象。 这使同步域能够读取和写入用户权限与服务器权限匹配的任何类型的对象。
auto updateSubscriptionSuccess = syncedRealm.subscriptions() .update([](realm::mutable_sync_subscription_set &subs) { subs.add<realm::Dog>("dogs"); }) .get(); // The .update() function returns a bool, which confirms whether or not the // update succeeded REQUIRE(updateSubscriptionSuccess == true); // You can check the .size() of the subscription set, which tells you the // number of sync_subscription objects in the set CHECK(syncedRealm.subscriptions().size() == 1);
订阅与查询匹配的对象
如果只想订阅对象的子集,请提供查询来筛选订阅。
updateSubscriptionSuccess = syncedRealm.subscriptions() .update([](realm::mutable_sync_subscription_set &subs) { subs.add<realm::Dog>( "puppies", [](auto &obj) { return obj.age < 3; }); }) .get(); REQUIRE(updateSubscriptionSuccess == true); CHECK(syncedRealm.subscriptions().size() == 1);
筛选订阅时,不能写入与筛选器不匹配的对象。 在此示例中,查询会匹配Dog
age
小于3
的 对象。Realm 不会同步任何年满 3 岁的狗。 此筛选器也适用于写入。 如果您尝试写入age
为4
的Dog
对象,则会出现补偿写入错误,并且写入会还原。
注意
C++ SDK 尚不支持其他 SDK 提供的全部查询表达式。
更新同步订阅
要更新订阅集,请使用subscription().updates()
函数。 这使您可以访问mutable_sync_subscription_set ,您可以在其中使用update_subscription()
函数更新特定的sync_subscription。
您可以在更新中更改sync_subscription
的查询。 您可以添加、删除或更新给定sync_subscription
的查询字符串。
updateSubscriptionSuccess = syncedRealm.subscriptions() .update([](realm::mutable_sync_subscription_set &subs) { subs.update_subscription<realm::Dog>( "puppies", [](auto &obj) { return obj.age < 2; }); }) .get(); REQUIRE(updateSubscriptionSuccess == true);
删除同步订阅
要更新订阅集,请使用subscription().updates()
函数。 这使您可以访问mutable_sync_subscription_set ,您可以在其中使用remove()
或clear()
函数删除订阅。
删除特定订阅
您可以使用remove()
函数按名称删除特定订阅。 如果订阅不存在,按名称删除订阅会引发错误,因此应在删除订阅之前检查是否存在订阅。
auto removeSubscriptionSuccess = syncedRealm.subscriptions() .update([](realm::mutable_sync_subscription_set &subs) { subs.remove("dogs"); }) .get(); REQUIRE(removeSubscriptionSuccess == true);
删除所有订阅
您可以使用clear()
函数删除订阅集中的所有订阅。
// You can use .clear() inside a mutable_sync_subscription_set to clear all // sync_subscription objects from the set auto updateSubscriptionSuccess = syncedRealm.subscriptions() .update( [](realm::mutable_sync_subscription_set &subs) { subs.clear(); }) .get(); CHECK(updateSubscriptionSuccess == true); CHECK(syncedRealm.subscriptions().size() == 0);
更新订阅后刷新 Realm
更新订阅后,调用Realm上的refresh()
。 这会更新 Realm 和该 Realm 管理的未完成对象,使其指向最新数据。
syncedRealm.refresh();