Skip to content

jonaswre/flutter_data

 
 

Repository files navigation

Flutter Data (Fork)

CI codecov license

Persistent reactive models in Flutter with zero boilerplate.

Forked from flutterdata/flutter_data. This fork adds SQLite-based local storage and is used by the ServiceApp project.

Requirements

  • Dart SDK >=3.1.0

Features

  • Adapters for all models -- Default CRUD and custom remote endpoints with StateNotifier watcher APIs
  • Built for offline-first -- SQLite3-based local storage at its core, with failure handling and retry API
  • Intuitive APIs, effortless setup -- Configurable and composable via Dart mixins and codegen, with built-in Riverpod providers
  • Exceptional relationship support -- Automatically synchronized, fully traversable and reactive relationship graph

Compatible with Flutter (or plain Dart), json_serializable, Freezed, Riverpod, and classic JSON REST APIs. Custom adapters can support Firebase, Supabase, GraphQL, and more.

Quick Start

Annotate a model with @DataAdapter and provide a custom adapter:

@JsonSerializable()
@DataAdapter([MyJSONServerAdapter])
class User extends DataModel<User> {
  @override
  final int? id;
  final String name;
  User({this.id, required this.name});
}

mixin MyJSONServerAdapter on RemoteAdapter<User> {
  @override
  String get baseUrl => "https://my-json-server.typicode.com/flutterdata/demo/";
}

After code generation, the resulting Adapter<User> is accessible via Riverpod:

@override
Widget build(BuildContext context, WidgetRef ref) {
  final state = ref.users.watchOne(1);
  if (state.isLoading) {
    return Center(child: const CircularProgressIndicator());
  }
  final user = state.model;
  return Text(user.name);
}

Save or update models directly:

ref.users.save(User(id: 1, name: 'Updated'));

Or use ActiveRecord-style extension methods:

User(id: 1, name: 'Updated').save();

Initialization

Supply a local storage provider via Riverpod, then initialize:

ProviderScope(
  overrides: [
    localStorageProvider.overrideWithValue(
      LocalStorage(
        baseDirFn: () async {
          return (await getApplicationSupportDirectory()).path;
        },
        busyTimeout: 5000,
        clear: LocalStorageClearStrategy.never,
      ),
    )
  ],
  // ...
),
return Scaffold(
  body: ref.watch(initializeFlutterData(adapterProvidersMap)).when(
    data: (_) => child,
    error: (e, _) => const Text('Error'),
    loading: () => const Center(child: CircularProgressIndicator()),
  ),
);

Development

# Install dependencies
dart pub get

# Run tests (requires libsqlite3-dev on Linux)
dart test

# Analyze
dart analyze

# Format
dart format .

Branches

The repo has both main and master branches. CI runs on both. The current default branch is master.

License

MIT

About

Seamlessly manage persistent data in your Flutter apps

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Dart 100.0%