Docs Menu
Docs Home
/ /
Servicios de aplicaciones Atlas

Tutorial: Sincronización de dispositivos Atlas para Flutter

Tiempo estimado para completar: 30 minutos, dependiendo de su experiencia con Flutter.

El SDK de dispositivos Atlas para Flutter permite crear aplicaciones multiplataforma con Dart y Flutter. Este tutorial se basa en la aplicación de plantilla de sincronización flexible de Flutter. flutter.todo.flex, que ilustra la creación de una aplicación de tareas pendientes. Esta aplicación permite a los usuarios:

  • Registrar su correo electrónico como una nueva cuenta de usuario.

  • Inicie sesión en su cuenta con su correo electrónico y contraseña (y cierre sesión más tarde).

  • Ver, crear, modificar y eliminar elementos de tarea.

  • Ver todas las tareas, incluso aquellas en las que el usuario no es el propietario.

La aplicación de plantilla también proporciona un interruptor que simula el dispositivo en modo sin conexión. Este interruptor permite probar rápidamente la sincronización del dispositivo, simulando que el usuario no tiene conexión a internet. Sin embargo, es probable que este interruptor se elimine en una aplicación de producción.

Este tutorial complementa la aplicación de plantilla. Agregará un nuevo priority campo al Item modelo existente y actualizará la suscripción de Sincronización Flexible para mostrar solo elementos dentro de un rango de prioridades.

Este tutorial ilustra cómo adaptar la aplicación de plantilla a sus necesidades. Dada la estructura actual de la aplicación, no es necesario realizar este cambio.

En este tutorial aprenderás a:

  • Actualice un modelo de objeto de Realm con un cambio ininterrumpido.

  • Actualizar una suscripción de sincronización de dispositivos

  • Agregue un campo consultable a la configuración de sincronización del dispositivo en el servidor para cambiar qué datos se sincronizan.

Si prefieres comenzar con tu propia aplicación en lugar de seguir un tutorial guiado, consulta la Guía deinicio rápido de Flutter. Incluye ejemplos de código copiables y la información esencial necesaria para configurar una aplicación con el SDK de Flutter.

  • Debes tener experiencia previa en la implementación de una aplicación Flutter en un emulador de Android, un simulador de iOS y/o un dispositivo físico.

Nota

Plataformas compatibles

Puedes compilar esta aplicación de tutorial en las siguientes plataformas:

  • iOS

  • Android

  • macOS

  • Windows

  • Linux

El SDK de Flutter no admite la creación de aplicaciones web.

Este tutorial se basa en la aplicación de plantilla de sincronización flexible de Flutter llamada flutter.todo.flex. Comenzamos con la aplicación predeterminada y creamos nuevas funciones a partir de ella.

Para obtener más información sobre las aplicaciones de plantilla, consulte Aplicaciones de plantilla.

Si aún no tiene una cuenta Atlas, regístrese para implementar una aplicación de plantilla.

Siga el procedimiento descrito en la guía Crear una aplicación de servicios de aplicaciones y seleccione Create App from TemplateSeleccione la plantilla Real-time Sync. Esto crea una aplicación de Servicios de Aplicaciones preconfigurada para usarla con uno de los clientes de la plantilla de Sincronización de Dispositivos.

Después de crear una aplicación de plantilla, la interfaz de usuario muestra un modal con la etiqueta Get the Front-end Code for your Template. Este modal proporciona instrucciones para descargar el código del cliente de la aplicación de plantilla como un archivo .zip o usar la CLI de App Services para obtener el cliente.

Después de seleccionar el método .zip o la CLI de App Services, siga las instrucciones en pantalla para obtener el código de cliente. Para este tutorial, seleccione el código de cliente Dart (Flutter).

Descomprime la aplicación descargada y verás la aplicación Flutter.

Nota

La utilidad ZIP predeterminada de Windows podría mostrar el archivo .zip vacío. Si esto ocurre, use un programa de compresión de terceros disponible.

El comando de creación de aplicaciones appservices configura el backend y crea una aplicación de plantilla Flutter para que la uses como base para este tutorial.

Ejecute el siguiente comando en una ventana de terminal para crear una aplicación llamada "MyTutorialApp" que se implementa en la región US-VA con su entorno configurado en "desarrollo" (en lugar de producción o control de calidad).

appservices app create \
--name MyTutorialApp \
--template flutter.todo.flex \
--deployment-model global \
--environment development

El comando crea un nuevo directorio en su ruta actual con el mismo nombre que el valor del indicador --name.

Puedes bifurcar y clonar un repositorio de GitHub que contenga el código del cliente de sincronización de dispositivos. El código del cliente de Flutter está disponible en https://github.com/mongodb/template-app-dart-flutter-todo.

Si usa este proceso para obtener el código del cliente, debe crear una aplicación de plantilla para usarla con el cliente. Siga las instrucciones de Crear una aplicación de plantilla para usar la interfaz de usuario de Atlas App Services, la CLI de App Services o la API de administración para crear una aplicación de plantilla de backend de Device Sync.

Clona el repositorio y sigue las instrucciones en README para agregar el ID de la aplicación de backend a la aplicación Flutter.

1

Abra la aplicación Flutter con su editor de código.

Si descargaste el cliente como archivo .zip o clonaste su repositorio de GitHub, debes insertar manualmente el ID de la aplicación de App Services en el lugar correspondiente del cliente. Sigue las instrucciones Configuration del cliente README.md para saber dónde insertar el ID de la aplicación.

2

En tu editor de código, dedica unos minutos a explorar la organización del proyecto. Se trata de una aplicación Flutter multiplataforma estándar, modificada para nuestro uso específico. En concreto, los siguientes archivos contienen usos importantes del SDK de Flutter:

Archivo
Propósito

lib/main.dart

Punto de entrada a la aplicación. Contiene enrutamiento y gestión de estado.

lib/realm/schemas.dart

Define el esquema de la base de datos de Realm.

lib/realm/schemas.realm.dart

Clase de objeto Realm generada.

lib/realm/app_services.dart

Maneja la interacción con Atlas App Services.

lib/realm/realm_services.dart

Maneja la interacción con la base de datos Realm y Atlas Device Sync.

lib/components/

Partes componentes de una aplicación con widgets de Flutter.

lib/screens/

Páginas de la aplicación.

3

Sin realizar ningún cambio en el código, debería poder ejecutar la aplicación en el emulador de Android, el simulador de iOS, el dispositivo móvil físico o el emulador de escritorio.

Primero, instale todas las dependencias ejecutando lo siguiente en su terminal:

flutter pub get

Luego, conéctelo a un dispositivo y ejecute la aplicación Flutter.

Una vez que la aplicación esté ejecutándose, registre una nueva cuenta de usuario y luego agregue un nuevo elemento a su lista de tareas pendientes.

Tip

Para obtener más información sobre cómo ejecutar una aplicación Flutter con herramientas de desarrollo, consulte la documentación de Flutter Test Drive.

4

Inicie sesión en MongoDB Atlas. En la pestaña, haga Data Services clic Browse Collections en. En la lista de bases de datos, busque y expanda la todo base de datos y, a continuación, la Item colección. Debería ver el documento que creó en esta colección.

1

Ahora que ha confirmado que todo funciona correctamente, podemos realizar cambios. En este tutorial, hemos decidido añadir una propiedad de "prioridad" a cada elemento para poder filtrarlos según su prioridad.

Para ello siga estos pasos:

  1. En el proyecto flutter.todo.flex, abra el archivo lib/realm/schemas.dart.

  2. Agregue la siguiente propiedad a la clase _Item:

    lib/realm/schemas.dart
    late int? priority;
  3. Regenerar la clase de objeto Realm Item:

    dart run realm generate
2
  1. En lib/realm/realm_services.dart, agrega lógica para establecer y actualizar priority. También agrega una clase abstracta PriorityLevel debajo de la clase RealmServices para restringir los valores posibles.

    lib/realm/realm_services.dart
    // ... imports
    class RealmServices with ChangeNotifier {
    static const String queryAllName = "getAllItemsSubscription";
    static const String queryMyItemsName = "getMyItemsSubscription";
    bool showAll = false;
    bool offlineModeOn = false;
    bool isWaiting = false;
    late Realm realm;
    User? currentUser;
    App app;
    // ... RealmServices initializer and updateSubscriptions(),
    // sessionSwitch() and switchSubscription() methods
    void createItem(String summary, bool isComplete, int? priority) {
    final newItem = Item(ObjectId(), summary, currentUser!.id,
    isComplete: isComplete, priority: priority);
    realm.write<Item>(() => realm.add<Item>(newItem));
    notifyListeners();
    }
    void deleteItem(Item item) {
    realm.write(() => realm.delete(item));
    notifyListeners();
    }
    Future<void> updateItem(Item item,
    {String? summary,
    bool? isComplete,
    int? priority}) async {
    realm.write(() {
    if (summary != null) {
    item.summary = summary;
    }
    if (isComplete != null) {
    item.isComplete = isComplete;
    }
    if (priority != null) {
    item.priority = priority;
    }
    });
    notifyListeners();
    }
    Future<void> close() async {
    if (currentUser != null) {
    await currentUser?.logOut();
    currentUser = null;
    }
    realm.close();
    }
    @override
    void dispose() {
    realm.close();
    super.dispose();
    }
    }
    abstract class PriorityLevel {
    static int severe = 0;
    static int high = 1;
    static int medium = 2;
    static int low = 3;
    }
  2. Añade un nuevo archivo que contenga un widget para establecer la prioridad de un elemento. Crea el archivo lib/components/select_priority.dart.

    lib/componentes/select_priority.dart
    import 'package:flutter/material.dart';
    import 'package:flutter_todo/realm/realm_services.dart';
    class SelectPriority extends StatefulWidget {
    int priority;
    void Function(int priority) setFormPriority;
    SelectPriority(this.priority, this.setFormPriority, {Key? key})
    : super(key: key);
    @override
    State<SelectPriority> createState() => _SelectPriorityState();
    }
    class _SelectPriorityState extends State<SelectPriority> {
    @override
    Widget build(BuildContext context) {
    return Padding(
    padding: const EdgeInsets.only(top: 15),
    child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    const Text('Priority'),
    DropdownButtonFormField<int>(
    onChanged: ((int? value) {
    final valueOrDefault = value ?? PriorityLevel.low;
    widget.setFormPriority(valueOrDefault);
    setState(() {
    widget.priority = valueOrDefault;
    });
    }),
    value: widget.priority,
    items: [
    DropdownMenuItem(
    value: PriorityLevel.low, child: const Text("Low")),
    DropdownMenuItem(
    value: PriorityLevel.medium, child: const Text("Medium")),
    DropdownMenuItem(
    value: PriorityLevel.high, child: const Text("High")),
    DropdownMenuItem(
    value: PriorityLevel.severe, child: const Text("Severe")),
    ],
    ),
    ],
    ),
    );
    }
    }
  3. Ahora, añade el widget SelectPriority a los widgets CreateItem y ModifyItem. También necesitas añadir lógica adicional para gestionar la configuración de la prioridad. El código que debes añadir se muestra a continuación.

    Algunas secciones de los archivos que estás agregando se reemplazan con comentarios en los siguientes ejemplos de código para enfocarse en las secciones de código relevantes que se modifican.

    Edita el widget CreateItemForm en lib/components/create_item.dart:

    lib/componentes/create_item.dart
    // ... other imports
    import 'package:flutter_todo/components/select_priority.dart';
    // ... CreateItemAction widget
    class CreateItemForm extends StatefulWidget {
    const CreateItemForm({Key? key}) : super(key: key);
    @override
    createState() => _CreateItemFormState();
    }
    class _CreateItemFormState extends State<CreateItemForm> {
    final _formKey = GlobalKey<FormState>();
    late TextEditingController _itemEditingController;
    int _priority = PriorityLevel.low;
    void _setPriority(int priority) {
    setState(() {
    _priority = priority;
    });
    }
    // ... initState() and dispose() @override functions
    @override
    Widget build(BuildContext context) {
    TextTheme theme = Theme.of(context).textTheme;
    return formLayout(
    context,
    Form(
    key: _formKey,
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
    // ... Text and TextFormField widgets
    SelectPriority(_priority, _setPriority),
    // ... Padding widget
    ],
    ),
    ));
    }
    void save(RealmServices realmServices, BuildContext context) {
    if (_formKey.currentState!.validate()) {
    final summary = _itemEditingController.text;
    realmServices.createItem(summary, false, _priority);
    Navigator.pop(context);
    }
    }
    }

    Edita el widget ModifyItemForm en lib/components/modify_item.dart:

    lib/componentes/modificar_elemento.dart
    // ... other imports
    import 'package:flutter_todo/components/select_priority.dart';
    class ModifyItemForm extends StatefulWidget {
    final Item item;
    const ModifyItemForm(this.item, {Key? key}) : super(key: key);
    @override
    _ModifyItemFormState createState() => _ModifyItemFormState(item);
    }
    class _ModifyItemFormState extends State<ModifyItemForm> {
    final _formKey = GlobalKey<FormState>();
    final Item item;
    late TextEditingController _summaryController;
    late ValueNotifier<bool> _isCompleteController;
    late int? _priority;
    void _setPriority(int priority) {
    setState(() {
    _priority = priority;
    });
    }
    _ModifyItemFormState(this.item);
    @override
    void initState() {
    _summaryController = TextEditingController(text: item.summary);
    _isCompleteController = ValueNotifier<bool>(item.isComplete)
    ..addListener(() => setState(() {}));
    _priority = widget.item.priority;
    super.initState();
    }
    @override
    void dispose() {
    _summaryController.dispose();
    _isCompleteController.dispose();
    super.dispose();
    }
    @override
    Widget build(BuildContext context) {
    TextTheme myTextTheme = Theme.of(context).textTheme;
    final realmServices = Provider.of<RealmServices>(context, listen: false);
    return formLayout(
    context,
    Form(
    key: _formKey,
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
    // ... Text and TextFormField widgets
    SelectPriority(_priority ?? PriorityLevel.medium, _setPriority),
    // ... StatefulBuilder widget
    Padding(
    padding: const EdgeInsets.only(top: 15),
    child: Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    cancelButton(context),
    deleteButton(context,
    onPressed: () =>
    delete(realmServices, item, context)),
    okButton(context, "Update",
    onPressed: () async => await update(
    context,
    realmServices,
    item,
    _summaryController.text,
    _isCompleteController.value,
    _priority)),
    ],
    ),
    ),
    ],
    )));
    }
    Future<void> update(BuildContext context, RealmServices realmServices,
    Item item, String summary, bool isComplete, int? priority) async {
    if (_formKey.currentState!.validate()) {
    await realmServices.updateItem(item,
    summary: summary, isComplete: isComplete, priority: priority);
    Navigator.pop(context);
    }
    }
    void delete(RealmServices realmServices, Item item, BuildContext context) {
    realmServices.deleteItem(item);
    Navigator.pop(context);
    }
    }
  4. Ahora, agregue un indicador visual de prioridad en el widget ItemCard de lib/components/todo_item.dart. Cree un nuevo widget _PriorityIndicator que proporcione un indicador visual de la prioridad del elemento.

    Añade un widget _PriorityIndicator que acabas de crear al widget TodoItem.

    lib/componentes/todo_item.dart
    // ... imports
    enum MenuOption { edit, delete }
    class TodoItem extends StatelessWidget {
    final Item item;
    const TodoItem(this.item, {Key? key}) : super(key: key);
    @override
    Widget build(BuildContext context) {
    final realmServices = Provider.of<RealmServices>(context);
    bool isMine = (item.ownerId == realmServices.currentUser?.id);
    return item.isValid
    ? ListTile(
    // ... leading property and child content
    title: Row(
    children: [
    Padding(
    padding: const EdgeInsets.only(right: 8.0),
    child: _PriorityIndicator(item.priority),
    ),
    SizedBox(width: 175, child: Text(item.summary)),
    ],
    ),
    // ... subtitle, trailing, and shape properties with child content
    )
    : Container();
    }
    // ... handleMenuClick() function
    }
    class _PriorityIndicator extends StatelessWidget {
    final int? priority;
    const _PriorityIndicator(this.priority, {Key? key}) : super(key: key);
    Widget getIconForPriority(int? priority) {
    if (priority == PriorityLevel.low) {
    return const Icon(Icons.keyboard_arrow_down, color: Colors.blue);
    } else if (priority == PriorityLevel.medium) {
    return const Icon(Icons.circle, color: Colors.grey);
    } else if (priority == PriorityLevel.high) {
    return const Icon(Icons.keyboard_arrow_up, color: Colors.orange);
    } else if (priority == PriorityLevel.severe) {
    return const Icon(
    Icons.block,
    color: Colors.red,
    );
    } else {
    return const SizedBox.shrink();
    }
    }
    @override
    Widget build(BuildContext context) {
    return getIconForPriority(priority);
    }
    }
3

Antes de volver a ejecutar la aplicación, realice un reinicio en caliente. Esto garantiza que la sesión de sincronización se reinicie con el nuevo esquema y evita errores de sincronización.

Luego, Iniciar sesión usando la cuenta que creaste anteriormente en este tutorial. Verás el único elemento que creaste anteriormente. Agrega un nuevo elemento, y verás que ahora puedes establecer la prioridad. Elija High para la prioridad y guarde el elemento.

Ahora, regrese a la página de datos del Atlas en su navegador y actualice la Item colección. Debería ver el nuevo elemento con el priority campo agregado y configurado como. También observará que el elemento existente ahora también tiene 1 un priority campo y está configurado como nulo, como se muestra en la siguiente captura de pantalla:

Dos artículos en una colección
haga clic para ampliar

Nota

¿Por qué no se rompió esta sincronizar?

Añadir una propiedad a un objeto Realm no supone un cambio drástico y, por lo tanto, no requiere restablecer el cliente. La aplicación de plantilla tiene habilitado el modo de desarrollo, por lo que los cambios en el objeto Realm del cliente se reflejan en el esquema del servidor. Para obtener más información, consulte Modo de desarrollo y Actualizar el modelo de datos.

Ahora que agregamos el campo de prioridad, queremos actualizar la suscripción de sincronización del dispositivo para sincronizar solo los elementos marcados como prioridad alta o grave.

1

En el archivo lib/realm/realm_services.dart, definimos la suscripción de Sincronización Flexible que define qué documentos sincronizamos con el dispositivo y la cuenta del usuario. Actualmente, sincronizamos todos los documentos cuya propiedad owner coincide con el usuario autenticado.

La suscripción actual:

lib/realm/realm_services.dart
Future<void> updateSubscriptions() async {
realm.subscriptions.update((mutableSubscriptions) {
mutableSubscriptions.clear();
if (showAll) {
mutableSubscriptions.add(realm.all<Item>(), name: queryAllName);
} else {
mutableSubscriptions.add(
realm.query<Item>(r'owner_id == $0', [currentUser?.id]),
name: queryMyItemsName);
}
});
await realm.subscriptions.waitForSynchronization();
}

Ahora vamos a cambiar la suscripción para que solo sincronice elementos de prioridad alta y grave. Como recordará, el campo de prioridad es de tipo int, donde la prioridad más alta ("Grave") tiene un valor de 0 y la más baja ("Baja") tiene un valor de 3.

Podemos realizar comparaciones directas entre un int y la propiedad de prioridad. Para ello, refactorizaremos la consulta de suscripción para incluir elementos cuya prioridad sea menor o igual a PriorityLevel.high (o 1). También asignaremos a la suscripción el nuevo nombre "getMyHighPriorityItemsSubscription".

Actualiza la suscripción para borrar la suscripción antigua y crear una nueva que utilice prioridad:

lib/realm/realm_services.dart
// ... imports
class RealmServices with ChangeNotifier {
static const String queryAllName = "getAllItemsSubscription";
static const String queryMyItemsName = "getMyItemsSubscription";
static const String queryMyHighPriorityItemsName =
"getMyHighPriorityItemsSubscription";
bool showAll = false;
bool offlineModeOn = false;
bool isWaiting = false;
late Realm realm;
User? currentUser;
App app;
RealmServices(this.app) {
if (app.currentUser != null || currentUser != app.currentUser) {
currentUser ??= app.currentUser;
realm = Realm(Configuration.flexibleSync(currentUser!, [Item.schema]));
showAll = (realm.subscriptions.findByName(queryAllName) != null);
// Check if subscription previously exists on the realm
final subscriptionDoesNotExists =
(realm.subscriptions.findByName(queryMyHighPriorityItemsName) ==
null);
if (realm.subscriptions.isEmpty || subscriptionDoesNotExists) {
updateSubscriptions();
}
}
}
Future<void> updateSubscriptions() async {
realm.subscriptions.update((mutableSubscriptions) {
mutableSubscriptions.clear();
if (showAll) {
mutableSubscriptions.add(realm.all<Item>(), name: queryAllName);
} else {
mutableSubscriptions.add(
realm.query<Item>(
r'owner_id == $0 AND priority <= $1',
[currentUser?.id, PriorityLevel.high],
),
name: queryMyHighPriorityItemsName);
}
});
await realm.subscriptions.waitForSynchronization();
}
// ... other methods
}
2

Ejecute la aplicación de nuevo. Inicie sesión con la cuenta que creó anteriormente en este tutorial.

Después de un momento inicial cuando Realm vuelve a sincronizar la colección de documentos, es posible que vea un mensaje de error similar al siguiente:

The following RangeError was thrown building StreamBuilder<RealmResultsChanges<Item>>(dirty, state:
_StreamBuilderBaseState<RealmResultsChanges<Item>, AsyncSnapshot<RealmResultsChanges<Item>>>#387c4):
RangeError (index): Invalid value: Only valid value is 0: 3

Este error puede ocurrir con el widget StreamBuilder al actualizarse la suscripción. En una aplicación de producción, se podría añadir gestión de errores. Sin embargo, para este tutorial, basta con realizar una actualización rápida y el error desaparecerá.

Ahora deberías ver el nuevo elemento de alta prioridad que creaste.

Tip

Cambiar suscripciones con el modo de desarrollador habilitado

En este tutorial, al cambiar la suscripción y la consulta en el campo de prioridad por primera vez, este se añade automáticamente a la sincronización de dispositivos Collection Queryable Fields. Esto se debe a que la aplicación de plantilla tiene el modo de desarrollo habilitado de forma predeterminada. Si el modo de desarrollo no estuviera habilitado, tendría que añadir manualmente el campo como consultable para usarlo en una consulta de sincronización del lado del cliente.

Para obtener más información, consulte Campos consultables.

Si desea probar la funcionalidad con más detalle, puede crear elementos con diferentes prioridades. Verá que un nuevo elemento con una prioridad menor aparece brevemente en la lista de elementos y luego desaparece. Realm crea el elemento localmente, lo sincroniza con el backend y lo elimina porque no cumple con las reglas de suscripción. Esto se denomina escritura compensatoria.

También notará que el documento que creó inicialmente no está sincronizado porque tiene una prioridad de null. Si desea que este elemento se sincronice, puede editarlo en la interfaz de usuario de Atlas y agregar un valor al campo de prioridad, o bien, puede cambiar su suscripción para incluir documentos con valores nulos. También le asignaremos a la suscripción el nuevo nombre "getUserItemsWithHighOrNoPriority".

lib/realm/realm_services.dart
class RealmServices with ChangeNotifier {
static const String queryAllName = "getAllItemsSubscription";
static const String queryMyItemsName = "getMyItemsSubscription";
static const String queryMyHighPriorityItemsName =
"getMyHighPriorityItemsSubscription";
static const String queryMyHighOrNoPriorityItemsName =
"getMyHighOrNoPriorityItemsSubscription";
bool showAll = false;
bool offlineModeOn = false;
bool isWaiting = false;
late Realm realm;
User? currentUser;
App app;
RealmServices(this.app) {
if (app.currentUser != null || currentUser != app.currentUser) {
currentUser ??= app.currentUser;
realm = Realm(Configuration.flexibleSync(currentUser!, [Item.schema]));
// Check if subscription previously exists on the realm
final subscriptionDoesNotExists =
realm.subscriptions.findByName(queryMyHighOrNoPriorityItemsName) ==
null;
if (realm.subscriptions.isEmpty || subscriptionDoesNotExists) {
updateSubscriptions();
}
}
}
Future<void> updateSubscriptions() async {
realm.subscriptions.update((mutableSubscriptions) {
mutableSubscriptions.clear();
if (showAll) {
mutableSubscriptions.add(realm.all<Item>(), name: queryAllName);
} else {
mutableSubscriptions.add(
realm.query<Item>(
r'owner_id == $0 AND priority IN {$1, $2, $3}',
[currentUser?.id, PriorityLevel.high, PriorityLevel.severe, null],
),
name: queryMyHighPriorityItemsName);
}
});
await realm.subscriptions.waitForSynchronization();
}
// ... other methods
}

Nuevamente, cuando se produce un error StreamBuilder la primera vez que abres la aplicación con la nueva suscripción, realiza una actualización rápida para ver los datos esperados.

Agregar una propiedad a un objeto Realm existente es un cambio importante y el modo de desarrollo garantiza que el cambio de esquema se refleje en el lado del servidor.

Nota

Compartir comentarios

¿Cómo te fue? Usa el Rate this page widget en la parte inferior derecha de la página para evaluar su efectividad. O reporta un problema en el repositorio de GitHub si tuviste algún problema.

Next

¿Qué son los servicios de aplicación Atlas?