Menu Docs
Página inicial do Docs
/ /
Serviços Atlas App

Tutorial: Atlas Device Sync para Flutter

Nesta página

  • Objetivos de aprendizagem
  • Pré-requisitos
  • Comece com o Modelo
  • Configurar o Aplicativo Modelo
  • Abra o aplicativo
  • Explore a estrutura do aplicativo
  • Execute o aplicativo
  • Verificar o Backend
  • Modificar a Aplicação
  • Adicionar uma nova propriedade
  • Adicionar uma nova propriedade ao modelo
  • Definir a prioridade ao criar e atualizar itens
  • Executar e testar
  • Alterar a assinatura
  • Atualizar a assinatura
  • Executar e testar
  • Conclusão
  • O que vem a seguir?

Tempo estimado para conclusão: 30 minutos, dependendo da sua experiência com o Flutter

O Atlas Device SDK for Flutter permite criar aplicativos de várias plataformas com o Dart e o Flutter. Este tutorial baseia-se no aplicativo Flutter Flexible Sync Template App, denominado flutter.todo.flex, que ilustra a criação de um aplicação Todo. Este aplicação permite que o usuário:

  • Registre seu e-mail como uma nova conta de usuário.

  • Faça login na conta deles com o e-mail e a senha (e saia mais tarde).

  • Visualize, crie, modifique e exclua itens de tarefa.

  • Visualizar todas as tarefas, mesmo onde o usuário não é o proprietário.

O aplicativo de modelo também oferece uma alternância que simula o dispositivo no "Modo Offline". Essa alternância permite que você teste rapidamente a Device Sync, emulando o usuário que não tem conexão com a internet. No entanto, você provavelmente removeria essa opção em um aplicativo de produção.

Este tutorial é adicionado ao aplicativo de modelo. Você adicionará um novo campo priority ao modelo de Item existente e atualizará a inscrição da Flexible Sync para mostrar apenas itens dentro de uma faixa de priorities.

Este tutorial ilustra como você pode adaptar o aplicativo modelo para suas próprias necessidades. Você não faria necessariamente esta alteração dada a estrutura atual do aplicativo modelo.

Neste tutorial, você aprenderá como:

  • Atualize um modelo de objeto Realm com uma alteração não inovadora.

  • Atualizar uma inscrição do Device Sync

  • Adicione um campo de query à configuração do Device Sync no servidor para alterar quais dados são sincronizados.

Se você preferir começar com seu próprio aplicação em vez de seguir um tutorial guiado, confira o Flutter Quick Start. Ele inclui exemplos de código copiáveis e as informações essenciais de que você precisa para configurar um aplicação Flutter SDK .

  • Você deve ter experiência anterior na implantação de aplicativos Flutter para um emulador Android, simulador iOS e/ou um dispositivo físico.

  • Este tutorial começa com um aplicativo de modelo. Você precisa de uma conta do Atlas, de uma chave de API e do App Services CLI para criar um aplicativo modelo.

    • Você pode aprender mais sobre a criação de uma conta do Atlas na documentação de Comece a usar o Atlas. Para este tutorial, você precisa de uma conta do Atlas com um cluster de camada livre.

    • Você também precisa de uma chave de API do Atlas para a conta do MongoDB Cloud com a qual deseja se conectar. Você deve ser proprietário do projeto para criar um aplicativo modelo usando o App Services CLI.

    • Para saber mais sobre como instalar o App Services CLI, consulte Instalar o App Services CLI. Após instalar, execute o comando login utilizando a chave API para seu projeto Atlas.

Observação

Plataformas suportadas

Você pode criar esse aplicativo tutorial nas seguintes plataformas:

  • iOS

  • Android

  • macOS

  • Windows

  • Linux

O Flutter SDK não oferece suporte à criação de aplicativos da web.

Este tutorial baseia-se no aplicativo do modelo da Sincronização flexível do Flutter denominado flutter.todo.flex. Começamos com o aplicativo padrão e construímos novos recursos nele.

Para saber mais sobre os aplicativos de modelo, consulte Aplicativos de modelo.

Se você ainda não tiver uma conta do Atlas, cadastre-se para implantar um Aplicativo Modelo.

Siga o procedimento descrito no guia Crie uma App Services App e selecione Create App from Template. Selecione o modelo Real-time Sync . Isso cria um App Services App pré-configurado para uso com um dos clientes da aplicação do modelo do Device Sync .

Após criar um aplicativo de modelo, a interface do usuário exibe um modal rotulado Get the Front-end Code for your Template. Esse modal fornece instruções para baixar o código do cliente do aplicativo modelo como um arquivo .zip ou usar a CLI do App Services para obter o cliente.

Após selecionar o método CLI do .zip ou App Services, siga as instruções na tela para obter o código do cliente. Para este tutorial, selecione o código de cliente Dart (Flutter).

Descompacte o aplicativo baixado e você verá o aplicativo Flutter.

Observação

O utilitário ZIP padrão do Windows pode mostrar o arquivo .zip arquivo como vazio. Se você encontrar isso, use um dos programas de compactação de terceiros disponíveis.

O comando appservices apps create configura o back-end e cria um aplicativo modelo Flutter para você usar como base para este tutorial.

Execute o seguinte comando em uma janela de terminal para criar um aplicativo chamado "MyTutorialApp" que é implantado na região US-VA com seu ambiente definido como "desenvolvimento" (em vez de produção ou controle de qualidade).

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

O comando cria um novo diretório no caminho atual com o mesmo nome do valor do sinalizador --name.

Você pode bifurcar e clonar um repositório do Github que contenha o código do cliente Device Sync . O código do cliente Flutter está disponível em https://github.com/mongodb/template-app-dart-flutter-todo.

Se você usar esse processo para obter o código do cliente, deverá criar um aplicativo modelo para usar com o cliente. Siga as instruções em Crie um aplicativo modelo para usar a interface do usuário do Atlas App Services, App Services CLI ou a Admin API para criar um aplicativo modelo de backend do Device Sync.

Clone o repositório e siga as instruções em README para adicionar o ID do aplicativo de back-end ao aplicativo Flutter.

1

Abra o aplicativo Flutter com seu editor de código.

Se você baixou o cliente como um arquivo .zip ou clonou o repositório GitHub do cliente, deverá inserir manualmente a ID do Aplicativo de Serviços de Aplicativo no local apropriado em seu cliente. Siga as instruções do Configuration no cliente README.md para saber onde inserir sua ID do aplicativo.

2

No editor de código, dedique alguns minutos para explorar como o projeto está organizado. Este é um aplicação Flutter multiplataforma padrão modificado para nosso uso específico. Especificamente, os seguintes arquivos contêm usos importantes do Flutter SDK:

arquivo
Propósito
lib/main.dart
Ponto de entrada no aplicativo. Contém roteamento e gerenciamento de estado.
lib/realm/schemas.dart
Define o esquema do Realm Database.
lib/realm/schemas.realm.dart
Classe de objeto de Realm gerada.
lib/realm/app_services.dart
Lida com a interação com o Atlas App Services.
lib/realm/realm_services.dart
Lida com a interação com Realm Database e Atlas Device Sync.
lib/components/
Partes componentes do aplicativo com widgets Flutter.
lib/screens/
Páginas do aplicativo.
3

Sem fazer alterações no código, você deve ser capaz de executar o aplicativo no emulador Android, simulador iOS, dispositivo móvel físico ou emulador de desktop.

Primeiro, instale todas as dependências executando o seguinte em seu terminal:

flutter pub get

Em seguida, conecte a um dispositivo e execute o aplicativo Flutter.

Quando o aplicativo estiver em execução, registre uma nova conta de usuário e, em seguida, adicione um novo item à sua lista de tarefas.

Dica

Para obter mais informações sobre como executar um aplicativo Flutter com ferramentas de desenvolvimento, consulte a documentação do Flutter Test Drive.

4

Conecte-se ao MongoDB Atlas. Na aba Data Services, clique em Browse Collections. Na lista de bancos de dados, localize e expanda o banco de dados do todo e, em seguida, a coleção do Item. Você deverá ver o documento que criou nesta coleção.

1

Agora que você confirmou que tudo está funcionando como o esperado, podemos adicionar alterações. Neste tutorial, decidimos que queremos adicionar uma propriedade "priority" a cada Item para que possamos filtrar os Itens por suas prioridades.

Para fazer isso, siga estas etapas:

  1. No projeto flutter.todo.flex, abra o arquivo lib/realm/schemas.dart.

  2. Adicione a seguinte propriedade à classe _Item:

    lib/realm/schemas.dart
    late int? priority;
  3. Gere novamente a classe de Objeto de Realm Item:

    dart run realm generate
2
  1. Em lib/realm/realm_services.dart, adicione lógica para definir e atualizar priority. Adicione também uma classe abstrata PriorityLevel abaixo da classe RealmServices para restringir os valores possíveis.

    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. Adicione um novo arquivo para conter um widget para definir a prioridade de um item. Crie o arquivo lib/components/select_priority.dart.

    lib/components/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. Agora adicione o widget SelectPriority aos widgets CreateItem e ModifyItem. Você também precisa incluir alguma lógica adicional para lidar com a configuração da prioridade. O código que você deve adicionar é mostrado abaixo.

    Algumas seções dos arquivos que você está adicionando são substituídos por comentários nos exemplos de código abaixo para se concentrarem nas seções de código alteradas.

    Edite o widget CreateItemForm em lib/components/create_item.dart:

    lib/components/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);
    }
    }
    }

    Edite o widget ModifyItemForm em lib/components/modify_item.dart:

    lib/components/modify_item.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. Agora adicione um indicador visual para prioridade no widget ItemCard no lib/components/todo_item.dart. Cria um novo widget _PriorityIndicator que fornece um indicador visual da prioridade do item.

    Adicione um widget _PriorityIndicator que você acabou de criar no widget TodoItem.

    lib/components/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 executar o aplicativo novamente, execute uma reinicialização a quente. Isso garante que a sessão de sincronização seja reiniciada com o novo esquema e evita erros de sincronização.

Em seguida, faça login usando a conta que você criou neste tutorial. Você verá o item que você criou anteriormente. Adicione um novo item e você verá que agora você pode definir a prioridade. Escolha High para a prioridade e salve o item.

Agora volte para a página de dados do Atlas em seu navegador e atualize a coleção do Item. Você deve agora visualizar o novo Item com o campo priority adicionado e configurado para 1. Você também notará que o Item existente agora também tem um campo priority e está configurado para nulo, como mostrado na seguinte captura de tela:

Dois itens em uma coleção
clique para ampliar

Observação

Por que isso não interrompeu a sincronização?

A adição de uma propriedade a um objeto Realm não é uma alteração de ruptura e, portanto, não exige uma reinicialização do cliente. O aplicativo de modelo tem o Modo de Desenvolvimento habilitado, portanto, as alterações no objeto Realm do cliente são refletidas no esquema do lado do servidor. Para obter mais informações, consulte Modo de desenvolvimento e Atualizar seu modelo de dados.

Agora que adicionamos o campo de prioridade, queremos atualizar a assinatura do Device Sync para sincronizar somente Itens marcados como prioridade Alta ou Severa.

1

No arquivo lib/realm/realm_services.dart, definimos a inscrição da Sincronização flexível que define quais documentos sincronizamos com o dispositivo e a conta do usuário. No momento, estamos sincronizando todos os documentos em que a propriedade owner corresponde ao usuário autenticado.

A inscrição atual:

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();
}

Agora, vamos alterar a inscrição para sincronizar apenas itens de priority alta e grave. Como você deve se lembrar, o campo de priority é do tipo int, em que a priority mais alta ("Severe") tem o valor 0 e a priority mais baixa ("Low") tem o valor 3.

Podemos fazer comparações diretas entre um int e a propriedade prioritária. Para isso, vamos refatorar a consulta de inscrição para incluir itens em que a priority seja menor ou igual a PriorityLevel.high (ou 1). Também daremos à inscrição o novo nome "getMyHighPriorityItemsSubscription".

Atualize a assinatura para excluir a assinatura antiga e adicionar uma nova que use prioridade:

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

Execute o aplicativo novamente. Faça login usando a conta que você criou neste tutorial.

Após um momento inicial, quando o Realm ressincroniza a coleção de documentos, você pode ver uma mensagem de erro semelhante à seguinte:

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 erro pode ocorrer com o widget StreamBuilder como a assinatura atualiza. Em um app de produção, você pode adicionar o tratamento de erros. Mas, para fins deste tutorial, basta realizar uma atualização rápida e o erro desaparecerá.

Agora você deve ver o novo Item de Alta priority que você criou.

Dica

Alterando assinaturas com o modo de desenvolvedor ativado

Neste tutorial, quando você altera a assinatura e a query no campo de prioridade pela primeira vez, o campo é adicionado automaticamente ao Device Sync Collection Queryable Fields. Isso ocorre porque o aplicativo de modelo tem o Modo de Desenvolvimento habilitado por padrão. Se o Modo de Desenvolvimento não estivesse habilitado, você teria que adicionar manualmente o campo como um campo consultável para usá-lo em uma query de sincronização do lado do cliente.

Para obter mais informações, consulte Campos consultáveis.

Se quiser testar ainda mais a funcionalidade, crie Itens de várias prioridades. Você verá um novo item com uma prioridade mais baixa aparecer brevemente na lista de itens e depois desaparecer. O Realm cria o Item localmente, sincroniza com o back-end e, em seguida, exclui o item porque não atende às regras de assinatura. Isso é chamado de gravação compensatória.

Você também notará que o documento que você criou inicialmente não está sincronizado, pois tem uma priority de null. Se quiser que esse item seja sincronizado, você pode editar o documento na UI do Atlas e adicionar um valor para o campo de priority, ou você pode alterar sua inscrição para incluir documentos com valores nulos. Também daremos à inscrição o novo nome "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
}

Novamente, quando um erro StreamBuilder ocorrer na primeira vez que você abrir o aplicativo com a nova inscrição, execute uma atualização instantânea para ver os dados esperados.

Adicionar uma propriedade a um objeto de Realm existente não é uma alteração significativa, e o modo de desenvolvimento garante que a alteração de esquema se reflita no lado do servidor.

Observação

Compartilhar feedback

Como foi? Use o widget Rate this page no canto inferior direito da página para avaliar sua eficácia. Ou registre um problema no repositório GitHub se você teve algum problema.

Próximo

O que são os Serviços de Aplicativo Atlas?