A Point of Sale (POS) application built with Flutter, demonstrating Clean Architecture principles and offline-first design patterns. This project serves as a learning resource and reference implementation for building Flutter apps with proper architecture and automatic data synchronization between local storage (SQLite) and cloud database (Firestore).
The app prioritizes local-first operations, storing all data in SQLite and automatically syncing with Firestore when online. When offline, all user actions (create, update, delete) are recorded as QueuedActions in the local database and automatically executed in sequence when internet connectivity is restored.
- Product Management: Full CRUD operations for products with image upload support
- Sales Transactions: POS interface with cart management and transaction history
- User Authentication: Firebase Authentication with Google Sign-In integration
- Account Management: User profile management and settings
- Offline-First Architecture: Works seamlessly without internet connection
- Automatic Data Sync: SQLite ↔ Firestore bidirectional synchronization
- Queued Actions: Automatic retry mechanism for offline operations (create, update, delete)
- Clean Architecture: Separation between presentation, domain, and data layers
- State Management: Provider pattern for state management
- Dependency Injection: Centralized DI setup for better code organization
- Unit Testing: Tests for datasources, repositories, and use cases
- Material Design 3: Material design 3 and Dark & Light theme switching support
- Customizable Theming: Adjustable colors and typography
- Multi-Platform: Supports Android, iOS, Windows, macOS, and Linux
- Error Handling: User-friendly error messages and states
- Reusable Widgets: Custom UI components for consistent design
flutter_pos/
├── lib/
│ ├── app/ # Application setup and configuration
│ │ ├── di/ # Dependency injection
│ │ ├── error/ # Error handling
│ │ └── routes/ # App routing and navigation
│ │
│ ├── core/ # Core utilities and shared resources
│ │ ├── assets/ # Asset management
│ │ ├── common/ # Common utilities (Result wrapper)
│ │ ├── constants/ # App constants
│ │ ├── database/ # Local database configuration (sqflite)
│ │ ├── extensions/ # Dart extensions
│ │ ├── locale/ # Localization
│ │ ├── services/ # Core services
│ │ ├── themes/ # App theming (colors, sizes, themes)
│ │ ├── usecase/ # Base usecase interface
│ │ └── utilities/ # Helper utilities (formatters, loggers, etc.)
│ │
│ ├── data/ # Data layer
│ │ ├── datasources/ # Data sources
│ │ │ ├── interfaces/ # Datasource interfaces
│ │ │ ├── local/ # Local datasources (sqflite)
│ │ │ └── remote/ # Remote datasources (Firestore, Firebase Auth)
│ │ ├── models/ # Data models with JSON serialization
│ │ └── repositories/ # Repository implementations
│ │
│ ├── domain/ # Domain layer (Business logic)
│ │ ├── entities/ # Business entities
│ │ ├── repositories/ # Repository interfaces
│ │ └── usecases/ # Use cases (business logic operations)
│ │
│ └── presentation/ # Presentation layer (UI)
│ ├── providers/ # State management (Provider)
│ ├── screens/ # UI screens
│ └── widgets/ # Reusable UI components
│
├── test/ # Unit and widget tests
└── assets/ # Assets files
-
Clone the repository:
git clone https://github.com/elrizwiraswara/flutter_pos.git cd flutter_pos -
Install dependencies:
flutter pub get
-
Set up Firebase:
- Create a new project on Firebase.
- Follow the instructions to add Firebase to your Flutter app here.
- Enable google authentication provider
- Update cloud firestore rules to allow read write operation
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null; } } }- Add cloud firestore indexes to enable query
- Update firebase storage rules to allow read write operation
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } } -
Set up your
config.jsonfile
GOOGLE_SERVER_CLIENT_IDisWeb client IDthat you can get from your Firebase Google sign-in method provider{ "GOOGLE_SERVER_CLIENT_ID": "xxxxxxxxxxxxx.apps.googleusercontent.com" } -
Run the application:
flutter run --dart-define-from-file config.json
To test the application, run the following command:
flutter test --coverageTo view the test coverage you can use genhtml or test_cov_console
Contributions are welcome! Please open an issue or submit a pull request for any bugs, feature requests, or improvements.
This project is licensed under the MIT License - see the LICENSE file for details.





