firestore_builder 0.1.6 copy "firestore_builder: ^0.1.6" to clipboard
firestore_builder: ^0.1.6 copied to clipboard

The easiest way to integrate Firestore into a Flutter application

example/lib/main.dart

// Example app for firestore_builder.
//
// Everything under `lib/firestore/` is generated from
// `firestore_builder_config.yaml` by `dart run firestore_builder`, then
// completed by `dart run build_runner build --delete-conflicting-outputs`.
// This file only shows how that generated code is used from a widget tree.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:example/firestore/models/team.dart';
import 'package:example/firestore/models/updated_value.dart';
import 'package:example/firestore/services/firestore_query_service.dart';
import 'package:example/firestore/states/team_states.dart';
import 'package:example/models/enums/team_size.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // This example is not wired to a Firebase project. To run it against
  // your own project, run `flutterfire configure` in this folder and pass
  // `options: DefaultFirebaseOptions.currentPlatform` below.
  await Firebase.initializeApp();
  // The generated providers need a ProviderScope above them.
  runApp(const ProviderScope(child: ExampleApp()));
}

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'firestore_builder example',
      home: TeamsPage(),
    );
  }
}

/// Lists the `teams` collection and lets the user add, edit and delete teams.
class TeamsPage extends ConsumerWidget {
  const TeamsPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // `teamCollectionProvider` is generated in `firestore/states/`.
    // It rebuilds this widget on every Firestore snapshot and is null until
    // the first snapshot arrives. Watch `teamCollectionStreamProvider`
    // instead if you need the full AsyncValue with its error state.
    final teams = ref.watch(teamCollectionProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Teams')),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _addTeam(ref),
        child: const Icon(Icons.add),
      ),
      body: switch (teams) {
        null => const Center(child: CircularProgressIndicator()),
        [] => const Center(child: Text('No team yet. Tap + to add one.')),
        final teams => ListView(
          children: [for (final team in teams) _TeamTile(team: team)],
        ),
      },
    );
  }

  Future<void> _addTeam(WidgetRef ref) async {
    // `Team` is a Freezed model generated in `firestore/models/`.
    // Fields declared with `accept_field_value: true` in the config get a
    // companion `<field>FieldValue` parameter. When set, it is written
    // instead of the plain value, so the server fills `created_at` here.
    final team = Team(
      name: 'Team ${DateTime.now().second}',
      userCount: 0,
      createdAt: DateTime.now(),
      createdAtFieldValue: FieldValue.serverTimestamp(),
      labels: const ['new'],
      teamSize: TeamSize.solo,
    );
    // `firestoreQueryServiceProvider` is generated in `firestore/services/`.
    // It exposes add, set, update, delete and get methods per collection.
    await ref.read(firestoreQueryServiceProvider).addTeam(team: team);
  }
}

enum _TeamAction {
  rename('Rename'),
  nextSize('Next team size'),
  addLabel('Add a label'),
  delete('Delete');

  const _TeamAction(this.label);

  final String label;
}

class _TeamTile extends ConsumerWidget {
  const _TeamTile({required this.team});

  final Team team;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ListTile(
      title: Text(team.name),
      subtitle: Text(
        '${team.teamSize.name} team, labels: ${team.labels.join(', ')}',
      ),
      trailing: PopupMenuButton<_TeamAction>(
        onSelected: (action) => _onAction(ref, action),
        itemBuilder: (context) => [
          for (final action in _TeamAction.values)
            PopupMenuItem(value: action, child: Text(action.label)),
        ],
      ),
    );
  }

  Future<void> _onAction(WidgetRef ref, _TeamAction action) async {
    final service = ref.read(firestoreQueryServiceProvider);
    // Every model carries its document id, filled when read from Firestore.
    final teamId = team.teamId;

    switch (action) {
      case _TeamAction.rename:
        // `updateTeam` takes one optional `UpdatedValue` per field and only
        // writes the fields you pass. Wrapping is what makes it possible to
        // update a nullable field to null: `description: UpdatedValue(null)`.
        await service.updateTeam(
          teamId: teamId,
          name: UpdatedValue('${team.name}!'),
        );
      case _TeamAction.nextSize:
        // Enum fields get a dedicated wrapper, generated next to
        // `UpdatedValue`, so the enum is serialized like it is in the model.
        const sizes = TeamSize.values;
        final next = sizes[(team.teamSize.index + 1) % sizes.length];
        await service.updateTeam(
          teamId: teamId,
          teamSize: UpdatedValueTeamSize(next),
        );
      case _TeamAction.addLabel:
        // `accept_field_value: true` fields can also be updated with any
        // Firestore `FieldValue`, here an atomic array union.
        await service.updateTeam(
          teamId: teamId,
          labelsFieldValue: UpdatedValue(FieldValue.arrayUnion(['edited'])),
        );
      case _TeamAction.delete:
        await service.deleteTeam(teamId: teamId);
    }
  }
}
4
likes
140
points
42
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

The easiest way to integrate Firestore into a Flutter application

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

code_builder, collection, dart_style, equatable, flutter, json_annotation, meta, pub_semver, recase, yaml

More

Packages that depend on firestore_builder