Design principles
The architecture follows these core principles:Separation of concerns
Each layer has a single, well-defined responsibility with minimal coupling between layers
Testability
Business logic is decoupled from the Android framework, enabling fast unit tests
Asynchronous by default
All data operations use Kotlin Coroutines and Flow to prevent UI thread blocking
Framework independence
Domain logic remains pure Kotlin, independent of Android or Firebase APIs
Architectural layers
The application is organized into four distinct layers that flow from the UI down to data sources:UI layer
Location:
ui/Built entirely with Jetpack Compose and Material Design 3- auth/ - Login, registration, and password recovery screens
- home/ - Main dashboard with phrase CRUD operations
- location/ - Geolocation display and address lookup
- nav/ - Navigation graph and routing logic
- theme/ - Material3 theming configuration
- Uses
@Composablefunctions for all UI - Implements reactive state management with
collectAsState() - Delegates all business logic to the Services layer
- Handles navigation via Jetpack Navigation Compose
Services layer
Location:
services/Acts as intermediary between UI and data/hardware- Data delegation - Wraps repository calls with error handling and mapping
- Hardware abstraction - Encapsulates Android APIs for speech and location
AuthService
AuthService
Manages authentication flow by delegating to
AuthRepository and mapping Firebase exceptions to user-friendly messages. Exposes reactive authentication state via Flow<FirebaseUser?>.PhraseService
PhraseService
Handles phrase CRUD operations with error handling and business logic validation.
LocationService
LocationService
Wraps
FusedLocationProviderClient and performs reverse geocoding using Geocoder. Handles API level differences for Android 13+.SpeechController
SpeechController
Manages
SpeechRecognizer lifecycle and provides callbacks for partial and final results.TextToSpeechController
TextToSpeechController
Controls Android’s TTS engine with Spanish (Chile) locale for accessibility features.
Domain layer
Location:
domain/Pure Kotlin with no Android or Firebase dependencies- models/ - Data classes (
AppUser,Phrase,DeviceLocation) - validators/ - Speech normalization algorithms and input validation
- errors/ - Custom exception types for error handling
- Fast to test (no Android SDK required)
- Reusable across platforms
- Independent of external APIs
Data layer
Location:
data/Handles all external data sources and persistence- repositories/ -
AuthRepository,PhraseRepository,LocationRepository,UserRepository - firebase/ - Firebase initialization module
- session/ - DataStore for local preferences
- All operations are suspending functions using Kotlin Coroutines
- Returns domain models, not Firebase objects
- Uses
Flowfor reactive data streams - Handles Firebase API calls with
.await()extension
Data flow example
Here’s how data flows through the layers when a user logs in:All Firebase operations are wrapped in
try-catch blocks at the Service layer to provide user-friendly error messages.Asynchronous architecture
The app uses Kotlin Coroutines and Flow throughout:- Coroutines - All repository methods are
suspendfunctions - Flow - Authentication state and data streams are reactive
- Dispatchers - Operations run on appropriate dispatchers (Main, IO)
- No blocking - UI thread is never blocked by data operations
Authentication state flow
The authentication state is managed reactively:- Converts Firebase callbacks to Kotlin Flow
- Automatically emits on authentication changes
- Properly cleans up listeners when collected
- Enables reactive UI updates via
collectAsState()
Technology stack
Language
Kotlin 1.9+ with Coroutines and Flow
UI Framework
Jetpack Compose with Material Design 3
Backend
Firebase Authentication and Firestore
Navigation
Jetpack Navigation Compose
Location
Google Play Services FusedLocationProviderClient
Testing
JUnit for unit tests
Next steps
Service-Repository pattern
Deep dive into the Service-Repository pattern implementation
Project structure
Detailed directory structure and file organization