An intuitive way to work with persistent data in Dart

Overview

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.
Comments
  • How can i delete associations in database

    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

    opened by polRk 17
  • Error in RestSerializable when hydrating after deletion

    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}";
          }
    
    opened by polRk 10
  • Is there any way to tell why I got an empty array from a get?

    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?

    opened by MilesAdamson 10
  • Current state of this project?

    Current state of this project?

    Hey guys,

    First of all: great project! You'd expect the issues solved by this to be more widespread and even natively supported by Flutter.

    Anyway, looking at this repository and trying to get it to run (I can't), I'm wondering if this project is abandoned or not? Do you have plans to maintain it into the foreseeable future? I'd love to help but I'm very new to Flutter and Dart.

    I noticed the links on GitHub are old (redirect to your blog), and I can't resolve the deps when following the setup guide:

    $ flutter pub get
    Because brick_offline_first_with_rest_build <1.0.0 depends on brick_offline_first_abstract ^0.0.8 and brick_offline_first_with_rest_build >=1.0.0 depends on brick_offline_first_abstract ^1.0.0+1, every version of brick_offline_first_with_rest_build requires brick_offline_first_abstract ^0.0.8 or ^1.0.0+1.
    Because brick_offline_first_with_rest >=1.0.0 depends on brick_offline_first_abstract ^2.0.0 and brick_offline_first_with_rest <1.0.0 depends on brick_offline_first_abstract ^2.0.0-rc.2, every version of brick_offline_first_with_rest requires brick_offline_first_abstract ^2.0.0-rc.2.
    Thus, brick_offline_first_with_rest_build is incompatible with brick_offline_first_with_rest.
    So, because test depends on both brick_offline_first_with_rest any and brick_offline_first_with_rest_build any, version solving failed.
    

    And my pubspec (clean new flutter project via Android Studio).

    dependencies:
      flutter:
        sdk: flutter
      cupertino_icons: ^1.0.2
      brick_offline_first_with_rest: any
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
      brick_offline_first_with_rest_build: any
      build_runner: any
    

    Flutter 3.0.5, Dart 2.17.5

    So any hope I can use this in a production environment?

    Cheers!

    opened by fvluijn 8
  • Work with MemoryCacheProvider

    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?

    opened by kirill09 8
  • build command fails due to a syntax error in generated code

    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?

    opened by diegonc 8
  • How to send parameters to the API endpoint?

    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.

    opened by guilhermedaldim 8
  • Query Argument for Get Method

    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

    opened by SubutaDan 7
  • Bug: Deleting when being offline

    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.

    opened by vandres 6
  • Can't create valid migrations file

    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

    opened by polRk 6
  • Bi-Modal Data Access

    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

    opened by SubutaDan 6
  • [Draft] Working on Adding Realm as an Option

    [Draft] Working on Adding Realm as an Option

    There's not too many differences between using Realm vs SQLite. I'm starting to explore this one in earnest. But it will take time. I'm bad with all the technologies here.

    This is not intended to be merged ever and mostly serve as an exploration page.

    opened by MarcusSorealheis 0
  • **Migrating to Brick 2 from Brick 1**

    **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.
    announcement 
    opened by tshedor 0
  • Ability not to await of remoteProvider upsert

    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)

    opened by pkozlovskiy 2
Owner
Dutchie
Delivering Happiness.
Dutchie
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

FlutterCandies 39 Nov 8, 2022
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

Gleb Batykov 39 Nov 14, 2022
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

Mohamed Ibrahim 11 Oct 24, 2022
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

AnTler 140 Dec 30, 2022
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

Bits Dojo 606 Dec 27, 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

Samilly Nunes 2 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

Samandar 1 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

Kesse 1 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.

Prashant Kumar Singh 10 Dec 3, 2022
Encrypted peer-to-peer system for data security. Own data, own privacy

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

CympleTech 455 Dec 26, 2022
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

Leo Farias 238 Jan 5, 2023
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

Nishant Andoriya 3 Jun 24, 2022
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

Batuhan Karababa 9 Oct 28, 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.

null 33 Oct 30, 2022
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

Murilo Benassi 2 Jul 26, 2022
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

Kevin Jacob 1 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

cosmic.horse 9 Oct 26, 2022
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

DEVSTRONS' 7 Dec 15, 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

FlutterQueen 3 Sep 24, 2022