A clean architecture notes application built with Flutter, Firebase, and Riverpod.
- Email/Password Sign Up
- Email/Password Login
- Logout functionality
- Session persistence (user stays logged in after app restart)
- Firebase Authentication integration
- Create notes
- Read/View notes
- Update/Edit notes
- Delete notes
- Real-time updates from Firestore
- User-specific notes (users can only see their own notes)
- Search notes by title
- Real-time search with instant results
- Clear search functionality
- Indigo & Purple color scheme
- Smooth animations and transitions
- Responsive layouts
- Loading states and error handling
- Empty states with helpful messages
lib/
├── core/
│ ├── constants/ # App-wide constants (colors, strings)
│ ├── errors/ # Error handling (failures)
│ └── utils/ # Utility functions (validators)
├── data/
│ ├── service/ # Firebase service
│ ├── models/ # Data models
│ └── repositories/ # Repository implementations
├── domain/
│ ├── entities/ # Business entities
│ ├── repositories/ # Repository interfaces
│ └── usecases/ # Business logic
└── presentation/
├── providers/ # Riverpod state management
├── screens/ # UI screens
└── widgets/ # Reusable widgets
- Model: Domain entities and data models for modularity
- View:Flutter widgets and screens
- ViewModel: Riverpod providers managing state
notes/
└── {noteId}/
├── id: String
├── title: String
├── content: String
├── userId: String
├── createdAt: Timestamp
└── updatedAt: Timestamp
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /notes/{noteId} {
// Users can only read their own notes
allow read: if request.auth != null &&
resource.data.userId == request.auth.uid;
// Users can only create notes with their own userId
allow create: if request.auth != null &&
request.resource.data.userId == request.auth.uid;
// Users can only update their own notes
allow update: if request.auth != null &&
resource.data.userId == request.auth.uid;
// Users can only delete their own notes
allow delete: if request.auth != null &&
resource.data.userId == request.auth.uid;
}
}
}
-
Email/Password authentication enabled for both login and sign up
-
User sessions persisted automatically by Firebase
- Flutter SDK (3.0.0 or higher)
- Android Studio / VS Code
- Firebase account
- Android device or emulator
git clone <your-repository-url>
cd notes_appflutter pub get- Create a Firebase Project
- Go to Firebase Console
- Create a new project or use an existing one
- Add an Android app to your Firebase project
- Register Your Android App
- Package name: com.example.notes_app
- Download google-services.json
- Place it in android/app/ directory
- Enable Authentication
- Go to Firebase Console > Authentication
- Enable Email/Password sign-in method
- Create Firestore Database
- Go to Firebase Console > Firestore Database
- Create database in production mode
- Apply the security rules provided above
- Update Firestore Indexes (if needed)
- The app uses orderBy('updatedAt', descending: true)
- Firebase will prompt you to create an index if needed
flutter doctor
flutter run
flutter build apk --releaseThe APK will be located at: build/app/outputs/flutter-apk/app-release.apk
- Each note contains a userId field
- Firestore security rules enforce user-specific access
- Users cannot see, edit, or delete other users' notes
- User signs up/logs in
- Firebase generates a unique uid
- All notes are created with the user's uid
- Queries filter by userId for security
- Firestore rules provide backend security
- Splash Screen: Initial loading and auth check
- Login Screen: Email/password login
- Signup Screen: New account creation
- Notes List: Display all user notes with search
- Note Detail: View note with edit/delete options
- Add/Edit Note: Create or modify notes
- Users have internet connectivity for Firebase operations
- Email/password is sufficient for authentication
- Simple note structure (title + content) is adequate
- Search by title only is sufficient atleast for version 1
- Clean Architecture: Adds more boilerplate but ensures maintainability and follows the SOLID principle
- Firebase: Vendor lock-in but allows for rapid development and saves cost.
- Client-side Search: Simple implementation, scales to thousands of notes
- No offline mode: Due to the simplicity of the assignment scope
- No offline support: Requires active internet connection
- Email-only auth: No social logins or phone authentication
- Basic search: Only searches note titles, not content
- No note sharing: Notes are private to each user
flutter build apk --debug
flutter build apk --release
- Single Responsibility Principle
- Dependency Inversion
- Separation of Concerns
- DRY (Don't Repeat Yourself)
- Robust try-catch blocks
- User-friendly error messages
- Smooth failure states
- Reactive programming with Riverpod
- Immutable state objects
- Clean state updates