An intuitive way to work with persistent data in Dart

Last update: May 19, 2022

An intuitive way to work with persistent data

An intuitive way to work with persistent data in Dart.

Full documentation

Why Brick?

What is Brick?

Brick is an extensible query interface for Dart applications. It's an all-in-one solution responsible for representing business data in the application, regardless of where your data comes from. Using Brick, developers can focus on implementing the application, without concern for where the data lives. Brick was inspired by the need for applications to work offline first, even if an API represents your source of truth.

Quick Start

  1. Add the packages:
    dependencies:
      # Or brick_offline_first_with_graphql
      brick_offline_first_with_rest: any
    dev_dependencies:
      # Or brick_offline_first_with_graphql_build: any
      brick_offline_first_with_rest_build: any
      build_runner: any
  2. Configure your app directory structure to match Brick's expectations:
    mkdir -p lib/brick/adapters lib/brick/db;
  3. Add models that contain your app logic. Models must be saved with the .model.dart suffix (i.e. lib/brick/models/person.model.dart).
  4. Run flutter pub run build_runner run to generate your models (or pub run build_runner run if you're not using Flutter) and sometimes migrations. Rerun after every new model change or flutter pub run build_runner watch for automatic generations.
  5. Extend an existing repository or create your own:
    // lib/brick/repository.dart
    import 'package:brick_offline_first/offline_first_with_rest.dart';
    import 'package:my_app/brick/brick.g.dart';
    import 'package:sqflite/sqflite' show databaseFactory;
    export 'package:brick_offline_first/offline_first_with_rest.dart' show And, Or, Query, QueryAction, Where, WherePhrase;
    
    class Repository extends OfflineFirstWithRestRepository {
      Repository()
          : super(
              migrations: migrations,
              restProvider: RestProvider(
                'http://0.0.0.0:3000',
                modelDictionary: restModelDictionary,
              ),
              sqliteProvider: SqliteProvider(
                _DB_NAME,
                databaseFactory: databaseFactory,
                modelDictionary: sqliteModelDictionary,
              ),
              offlineQueueManager: RestRequestSqliteCacheManager(
                'brick_offline_queue.sqlite',
                databaseFactory: databaseFactory,
              ),
            );
    }
  6. Profit.

GitHub

https://github.com/greenbits/brick
Comments
  • 1. How can i delete associations in database

    One Task has many project.

    final task = Task(projects: [Project()],);
    

    If I delete all projects

    task.projects.clear();
    

    call update

    update<Task>(task);
    

    And brick does not delete the associations in the database

    Reviewed by polRk at 2020-12-24 20:18
  • 2. Error in RestSerializable when hydrating after deletion

    TaskDto

    @ConnectOfflineFirstWithRest(
      restConfig: RestSerializable(
        fieldRename: FieldRename.none,
        fromKey: 'items',
        endpoint: r'''{
          if (query.action == QueryAction.get && query?.where != null) {
            final byId = Where.firstByField('id', query.where);
    
            if (byId?.value != null) {
              return "/tasks/${byId.value}";
            }
          }
    
          if (query?.action == QueryAction.delete) {
            return "/tasks/${instance.id}";
          }
    
          return "/tasks";
        }''',
      ),
    )
    

    flutter: FINEST: 2020-12-10 11:37:36.095433: #delete: url= statusCode=200 body= flutter: FINEST: 2020-12-10 11:37:36.096858: #hydrate: TaskDto {"action":4,"providerArgs":{}} [VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The getter 'id' was called on null. Receiver: null Tried calling: id

    Error in this line

          if (query?.action == QueryAction.delete) {
            return "/tasks/${instance.id}";
          }
    
    Reviewed by polRk at 2020-12-10 08:41
  • 3. Is there any way to tell why I got an empty array from a get?

    Issue: when I'm loading a list of jobs with requireRemote = true, I get an empty list of jobs when any error happens at all. An empty list of jobs due to no work to be done and an empty list because there was an http error is very different.

    I would like to be able to catch http errors or at least receive null to know something went wrong. Is this possible?

    Reviewed by MilesAdamson at 2020-05-22 18:07
  • 4. Work with MemoryCacheProvider

    Hi thanks for the great library. Working with MemoryCacheProvider found the following code:

    if (memoryCacheProvider.canFind<_Model>(query)) {
        final results = memoryCacheProvider.get<_Model>(query: query, repository: this);
    
        return results?.isNotEmpty ?? false;
    }
    
    return await sqliteProvider.exists<_Model>(query: query, repository: this);
    

    https://github.com/greenbits/brick/blob/master/packages/brick_offline_first/lib/src/offline_first_repository.dart#L116

    Why, if we did not find the data in the memoryCacheProvider, do we return false. It seems to me that there should be a request for sqliteProvider.exists?

    Reviewed by kirill09 at 2021-07-21 12:21
  • 5. build command fails due to a syntax error in generated code

    In a new flutter project I added the dependencies on brick

    environment:
      sdk: ">=2.7.0 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
      brick_offline_first: any
    
    
      # The following adds the Cupertino Icons font to your application.
      # Use with the CupertinoIcons class for iOS style icons.
      cupertino_icons: ^1.0.2
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
      brick_offline_first_with_rest_build:
        git:
          url: https://github.com/greenbits/brick.git
          path: packages/brick_offline_first_with_rest_build
      build_runner: any
    

    When I run the build command ( flutter pub run build_runner build --verbose ) I get the following error:

    [SEVERE] brick_offline_first_with_rest_build:brickAdaptersBuilder on lib/app/models/product_variant.dart (cached):
    
    Could not format because the source could not be parsed:
    
    line 2, column 56 of .: Expected to find ')'.
      ╷
    2 │         return ProductVariant(id:  data['id'] as String*,
      │                                                        ^
      ╵
    package:dart_style/src/dart_formatter.dart 138:7               DartFormatter.formatSource
    package:dart_style/src/dart_formatter.dart 71:12               DartFormatter.format
    package:brick_build/src/serdes_generator.dart 249:23           SerdesGenerator.generate
    package:brick_build/src/adapter_generator.dart 54:25           AdapterGenerator.serializerFunctions.<fn>
    dart:collection                                                ListMixin.fold
    package:brick_build/src/adapter_generator.dart 53:23           AdapterGenerator.serializerFunctions
    package:brick_build/src/adapter_generator.dart 72:8            AdapterGenerator.generate
    package:brick_build/src/annotation_super_generator.dart 33:29  AnnotationSuperGenerator.generateAdapter
    package:brick_build/src/builders/adapter_builder.dart 24:32    AdapterBuilder.build
    

    The test project is at https://github.com/diegonc/test_brick and the entity at https://github.com/diegonc/test_brick/blob/master/lib/app/models/product_variant.dart

    flutter doctor output is:

    $ flutter doctor -v
    [✓] Flutter (Channel stable, 2.0.5, on Linux, locale es_AR.UTF-8)
        • Flutter version 2.0.5 at /home/diegonc/dev/tools/flutter
        • Framework revision adc687823a (hace 10 días), 2021-04-16 09:40:20 -0700
        • Engine revision b09f014e96
        • Dart version 2.12.3
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at /home/diegonc/Android/Sdk
        • Platform android-30, build-tools 30.0.3
        • Java binary at: /home/diegonc/dev/tools/android-studio/jre/bin/java
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
        • All Android licenses accepted.
    
    [✓] Chrome - develop for the web
        • Chrome at google-chrome
    
    [✓] Android Studio
        • Android Studio at /home/diegonc/dev/tools/android-studio
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • android-studio-dir = /home/diegonc/dev/tools/android-studio
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    
    [✓] VS Code (version 1.55.2)
        • VS Code at /usr/share/code
        • Flutter extension can be installed from:
          🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
    
    [✓] Connected device (1 available)
        • Chrome (web) • chrome • web-javascript • Google Chrome 88.0.4324.182
    
    • No issues found!
    

    Any idea why the syntax error is happening or how to debug it?

    Reviewed by diegonc at 2021-04-26 18:31
  • 6. How to send parameters to the API endpoint?

    I'm using the OfflineFirstWithRestModel in my application, but I still couldn't configure my model in the expected way.

    What is the correct way to send parameters to the API endpoint? I need to filter calls according to some fields returned by the endpoints

    I've tried to send by query -> providerArgs and query -> where. But in both cases, when the app is offline I don't get a response from the db, affecting the functioning of the app.

    Reviewed by guilhermedaldim at 2020-08-20 18:13
  • 7. Query Argument for Get Method

    Hello, I want to pass an entity to a Repository.get method so I can use a field from the entity as a query parameter. From the example program on Flutter by Example it seems that I should be able to do that, but my get method doesn't accept an instance variable:

    //I can't do this: Repository().get<MyModelType>(myModelInstance); because I get:

    Too many positional arguments: 0 expected, but 1 found.

    Is passing instance variables to Repository.get methods supported? How can I pass a value to be used as a query parameter for a get? Thanks. -Dan

    Reviewed by SubutaDan at 2021-01-03 17:19
  • 8. Bug: Deleting when being offline

    Hi.

    When tying to delete a model when being offline, an exception is thrown. Syncing still works, after going back online.

    When upserting a model while being offline, no error is thrown.

    Reviewed by vandres at 2021-07-11 11:23
  • 9. Can't create valid migrations file

    I do not know what the problem is, but when you start the build, brick deletes all the columns and then creates them again

    
      brick_offline_first_with_rest_build:
        git:
          url: https://github.com/greenbits/brick.git
          path: packages/brick_offline_first_with_rest_build
      build_runner: any
    

    I think that after you added null safety, I lost the generation migration mechanism

    Reviewed by polRk at 2021-04-22 13:57
  • 10. Bi-Modal Data Access

    The data that is returned by my API may be changed (items added, updated and deleted) from outside of my app. I am looking for a way to resync the contents of the applications's Brick sqlite database from REST from time to time to reflect those external changes. I think I can force new items to be added to the sqlite database and existing items to be updated in the sqlite database by doing a get with requireRemote set to true, although I am not 100% confident about my testing methodology. The same testing seems to indicate that doing a get with requireRemote set to true will not cause items that have been removed from outside of the application to be removed in the application's Brick sqlite database.

    Do my conclusions sound correct? If so, is there a way to get the items that were deleted from outside of the app to be removed from the application's Brick sqlite database?

    Many thanks.

    -Dan

    Reviewed by SubutaDan at 2020-12-17 01:15
  • 11. Handling 401 Unauthorized Response

    I am using passport for api connection, but when client response 401 due to an expired token , brick ignore this response and continue retrieve data from local.

    it seems brick ignore 401 http code , It is possible to get an Unauthorized exception ?

    I have to say , brick is a really nice package. helps me a lot.

    Thanks in advance

    Reviewed by carlos-labrador at 2020-04-03 04:50
  • 12. **Migrating to Brick 2 from Brick 1**

    Brick 2 focuses on Brick problems encountered at scale. While the primary refactor was the abstraction of domain-specific code from generalized domains, this major release also includes a new GraphQL domain, resolution of community pain points, and a few neat tricks.

    Please follow the guide below to mitigate the breaking changes (shell commands are run at your own risk).

    And please respond to this issue or open a new one if you have any difficulty.

    Breaking Changes

    • Brick no longer expects lib/app; it now expects lib/brick.
      mv -r lib/app lib/brick
      
    • Models are no longer discovered in lib/app/models; they are now discovered via *.model.dart. They can live in any directory within lib and have any prefix. (#38)
      for FILENAME in lib/brick/models/*; do mv $FILENAME "${FILENAME/dart/model.dart}"; done
      
    • brick_offline_first is now, fundamentally, brick_offline_first_with_rest. brick_offline_first now serves as an abstract bedrock for offline domains.
      sed -i '' 's/brick_offline_first:/brick_offline_first_with_rest:/g' pubspec.yaml
      for FILE in $(find "lib" -type f -name "*.dart"); do sed -i '' 's/package:brick_offline_first/package:brick_offline_first_with_rest/g' $FILE; done
      
    • brick_offline_first_abstract is now brick_offline_first_with_rest_abstract
      sed -i '' 's/brick_offline_first_abstract:/brick_offline_first_with_rest_abstract:/g' pubspec.yaml
      for FILE in $(find "lib" -type f -name "*.dart"); do sed -i '' 's/package:brick_offline_first_abstract/package:brick_offline_first_with_rest_abstract/g' $FILE; done
      
    • rest properties have been removed from OfflineFirstException. Use OfflineFirstWithRestException instead from brick_offline_first_with_rest.
    • OfflineFirstRepository#get(requireRemote: and OfflineFirstRepository#getBatched(requireRemote: has been removed. Instead, use policy: OfflineFirstGetPolicy.alwaysHydrate
    • OfflineFirstRepository#get(hydrateUnexisting: has been removed. Instead, use policy: OfflineFirstGetPolicy.awaitRemoteWhenNoneExist (this is the default).
    • OfflineFirstRepository#get(alwaysHydrate: has been removed. Instead, use policy: OfflineFirstGetPolicy.alwaysHydrate.

    Fun Changes

    • Utilize OfflineFirstDeletePolicy, OfflineFirstGetPolicy, and OfflineFirstUpsertPolicy to override default behavior. Specific policies will throw an exception when the remote responds with an error (and throw that error) or skip the queue. Existing default behavior is maintained.
    • OfflineFirstRepository#delete now supports requiring a successful remote with OfflineFirstDeletePolicy.requireRemote. If the app is offline, normally handled exceptions (ClientException and SocketException) are rethrown. (#182)
    • OfflineFirstRepository#upsert now supports requiring a successful remote with OfflineFirstUpsertPolicy.requireRemote. If the app is offline, normally handled exceptions (ClientException and SocketException) are rethrown.

    Seven New Packages

    • brick_graphql. The GraphqlProvider interfaces with a GraphQL backend. It uses gql's Link system to integrate with other community-supported functionality. That, and all your variables are autogenerated on every request.
    • brick_graphql_generators. The perfect companion to brick_graphql, this thin layer around brick_rest_generators battle-tested core compiles adapters for the GraphQL domain.
    • brick_json_generators. The experienced core separated from brick_rest_generators permits more code reuse and package creation for JSON-serving remote providers.
    • brick_offline_first_build. Abstracted from the experienced core of brick_offline_first_with_rest_build, these helper generators and utils simplify adding offline capabilites to a domain.
    • brick_offline_first_with_graphql. Utilize the GraphQL provider with SQLite and Memory cache. This is a near mirror of brick_offline_first_with_rest, save for a few exceptions. First, the OfflineQueueLink must be inserted in the appropriate position in your client's Link chain. Second, OfflineFirstWithGraphqlRepository#subscribe permits streaming updates, including notifications after local providers are updated.
    • brick_offline_first_with_graphql_abstract. Annotations for the GraphQL domain without including Flutter.
    • brick_offline_first_with_graphql_build. The culmination of brick_graphql_generators and brick_offline_first_build.
    Reviewed by tshedor at 2022-02-16 19:59
  • 13. Ability not to await of remoteProvider upsert

    According to the concept offline first i want immediately after sqliteProvider upsert get actual associations. For example I show Customers with its pizzas, and then according with my UX change some pizza name and immediately(after sqliteProvider.upsert) show Customers with new pizzas.(I assume that pizzas has one to many relationships)

    Reviewed by pkozlovskiy at 2021-02-09 07:48

Related

The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that frozened column/row,loading more, high performance and better experience in TabBarView/PageView.
The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that frozened column/row,loading more, high performance and better experience in TabBarView/PageView.

flex_grid Language: English| 中文简体 The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that f

Apr 5, 2022
Actor model implementation in Dart. This package makes it easier to work with isolates, create clusters of isolates.
Actor model implementation in Dart. This package makes it easier to work with isolates, create clusters of isolates.

Actor model implementation in Dart Languages: Introduction About Theater Installing What is Actor Notes about the actors Actor system Actor tree Using

May 19, 2022
Encrypted peer-to-peer system for data security. Own data, own privacy
Encrypted peer-to-peer system for data security. Own data, own privacy

ESSE (Encrypted Symmetrical Session Engine) An open source encrypted peer-to-pee

May 22, 2022
Learn to build apps that work on Android, iOS, Web, and Desktop
Learn to build apps that work on Android, iOS, Web, and Desktop

Cross-Platform Development with Flutter Course Learn to build apps that work on Android, iOS, Web, and Desktop Go To Course Flutter is Google’s UI too

Mar 20, 2022
A Flutter package that makes it easy to customize and work with your Flutter desktop app's system tray.
A Flutter package that makes it easy to customize and work with your Flutter desktop app's system tray.

system_tray A Flutter package that that enables support for system tray menu for desktop flutter apps. on Windows, macOS and Linux. Features: - Modify

May 17, 2022
A Flutter package that makes it easy to customize and work with your Flutter desktop app window.
A Flutter package that makes it easy to customize and work with your Flutter desktop app window.

bitsdojo_window A Flutter package that makes it easy to customize and work with your Flutter desktop app window on Windows, macOS and Linux. Watch the

May 23, 2022
An admin panel aplication written with Flutter, aiming work with apps responsiveness.

admin_panel A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if t

Oct 23, 2021
My flutter projects work with JSON

Apps work with JSON A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you star

Oct 21, 2021
Worney - help people that want to know what time have been made on work time

Worney - help people that want to know what time have been made on work time

Mar 10, 2022
A cryptocurrency, crypto-currency, or crypto is a digital currency designed to work as a medium of exchange through a computer network that is not reliant on any central authority

A cryptocurrency, crypto-currency, or crypto is a digital currency designed to work as a medium of exchange through a computer network that is not reliant on any central authority, such as a government or bank, to uphold or maintain it.

May 6, 2022
An expressive way to effortlessly build design systems in Flutter.
An expressive way to effortlessly build design systems in Flutter.

An expressive way to effortlessly build design systems in Flutter. Mix offers primitive building blocks to help developers and designers create beauti

May 22, 2022
A news application that fetches the latest news via an API and displays, in a reverse sorted chronological way.
     A news application that fetches the latest news via an API and displays, in a reverse sorted chronological way.

News App Description A news application that fetches the latest news via an API and displays, in a reverse sorted chronological way. Features Nativ Sp

Sep 1, 2021
This is not an app. I made this architecture to build robust and easy-to-maintain products but in a faster way.

simple_architecture_flutter This is not an app. I made this architecture to build robust and easy-to-maintain products but in a faster way. Info I use

May 22, 2022
A Flutter application for Muslims that help them challenge and motivate themselves and their friends to read Azkar in a fun way.
A Flutter application for Muslims that help them challenge and motivate themselves and their friends to read Azkar in a fun way.

A Flutter application for Muslims that help them challenge and motivate themselves and their friends to read Azkar in a fun way.

Apr 2, 2022
Create a simple way to keep track of weekly expenses with flutter
Create a simple way to keep track of weekly expenses with flutter

Expenses app The purpose of this app is to create a simple way to keep track of weekly expenses UI Getting Started This project is a starting point fo

Oct 19, 2021
An app that could help doctors better consult their patients in every way possible.

doc_app A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this

Oct 15, 2021
cosmic_frontmatter is a package that provides a simple way to parse the frontmatter of a markdown file.

cosmic_frontmatter cosmic_frontmatter is a package that provides a simple way to parse the frontmatter of a markdown file. Getting started To get star

Nov 2, 2021
Helping navigate through maps to prefer road-way.

pothole-detector Detecting potholes using a smartphone app, & display the data to users over maps (google or open-street) through a app. In future, th

Apr 27, 2022
small package to generate code in a simple way

PART OF QUEEN PACKAGES ?? Dart File Builder Motivation generating dart code with build_runner will not work if you are trying to convert json to dart

May 6, 2022