A stateful Flutter app backed by Firebase Firestore with full CRUD operations on a real-time synchronized task list, including nested subtasks.
A search bar at the top of the task list filters tasks by title in real time as the user types. The filter is applied client-side on the streamed list, so it is instant with no extra Firestore reads. Clearing the search restores the full list immediately.
The app uses ThemeMode.system in MaterialApp, so it automatically switches between light and dark themes based on the device's system setting. Both themes use Material 3 with a consistent deep-purple color scheme. No extra user interaction is required.
- Flutter SDK (3.x or later)
- Dart SDK
- A Firebase project with Firestore enabled
- FlutterFire CLI:
dart pub global activate flutterfire_cli
-
Clone the repository
git clone <your-repo-url> cd task_manager
-
Configure Firebase
flutterfire configure
This generates
lib/firebase_options.dartlinked to your Firebase project. -
Enable Firestore
- Go to console.firebase.google.com
- Select your project → Firestore Database → Create database → Start in test mode
-
Install dependencies
flutter pub get
-
Run the app
flutter run
-
Build APK
flutter build apk --release
The APK will be at
build/app/outputs/flutter-apk/app-release.apk
lib/
├── main.dart # App entry point, Firebase init, theme setup
├── firebase_options.dart # Auto-generated by FlutterFire CLI
├── models/
│ └── task.dart # Task data model with toMap, fromMap, copyWith
├── services/
│ └── task_service.dart # All Firestore CRUD operations
├── screens/
│ └── task_list_screen.dart # Main screen with StreamBuilder + search
└── widgets/
└── task_card.dart # Expandable task card with subtask support
- No user authentication — all users share the same Firestore collection
- Firestore security rules are in development mode (open read/write); tighten before production use
- Search filters only by task title, not subtask content
- Due date input uses a date picker only (no time selection)
- No offline persistence enabled (tasks require a network connection to load)