A reference Android application for students
An educational example project demonstrating common Android development patterns — Single Activity + MVVM architecture, fragment navigation, authentication, CRUD operations, and a swappable Firebase backend (Cloud Firestore or Realtime Database).
- Features
- Tech Stack
- Project Structure
- Getting Started
- Architecture
- Screen Flow
- Adding a New Screen
- Switching the Database Backend
- License
| Feature | Description |
|---|---|
| 🔐 Authentication | Register and log in; the session is kept in SharedPreferences |
| 👤 User Profile | View and edit your profile; admins can view and edit any user |
| 🛒 Carts | Build a cart from food items, view your carts and their details |
| 🍕 Food Management | Add food items with a name, price, and photo |
| 🛡️ Admin Panel | Browse all users, all food items, and all carts |
| 📷 Images | Camera / gallery picker; images stored as base64 (WEBP) |
| ☁️ Cloud Database | Cloud Firestore (default) or Firebase Realtime Database |
| Technology | Details |
|---|---|
| Language | Java 17 |
| Compile / Min / Target SDK | 35 (Android 15) |
| Build System | Gradle 9.8.2, Android Gradle Plugin 8.10.1 |
| Architecture | Single Activity, MVVM (AndroidX ViewModel + LiveData) |
| UI | AndroidX Fragment 1.9.1, RecyclerView 1.4.0, Material Components 1.12.0 |
| Database | Firebase BoM 33.9.0 — Cloud Firestore & Realtime Database |
| Serialization | Gson 2.11.0 (stores the logged-in user locally) |
app/src/main/java/com/example/testapp/
│
├── MainActivity.java # The only Activity — hosts every screen, implements NavigationHost
├── 📂 core/ # BaseFragment, NavigationHost, ViewModelFactory
├── 📂 screens/ # One folder per screen: <Name>Fragment + <Name>ViewModel
├── 📂 models/ # Data entities: User, Food, Cart (+ Identifiable)
├── 📂 services/ # Data-access interfaces + DatabaseService backend switcher
│ └── 📂 impl/
│ ├── 📂 firestore/ # Cloud Firestore implementations (default)
│ └── 📂 rtdb/ # Realtime Database implementations
├── 📂 adapters/ # RecyclerView / list adapters
└── 📂 utils/ # Validator, ImageUtil, SharedPreferencesUtil
Each folder has its own README.md with details.
- Android Studio (recent stable release)
- JDK 17+ to run Gradle
- A Firebase project with Cloud Firestore enabled (and/or Realtime Database)
- An emulator or device running Android 15 (API 35) or newer
# 1. Clone the repository
git clone https://github.com/gilyerm/TestApp.git
# 2. Open the project in Android Studio
# 3. Put your google-services.json in the app/ directory
# 4. Sync Gradle, then run on an emulator/device (API 35+)Build from the command line:
./gradlew assembleDebug # build the debug APK
./gradlew testDebugUnitTest # run unit testsNote
google-services.json is not in the repository. Create your own Firebase project and download the file from the Firebase Console.
The app uses a Single Activity Architecture with MVVM. MainActivity is the only Activity; every screen is a Fragment with its own ViewModel.
┌──────────────────────────────────────────────┐
│ MainActivity (implements NavigationHost) │ ← toolbar + fragment container
├──────────────────────────────────────────────┤
│ screens/<name>/<Name>Fragment │ ← View: renders UI, observes LiveData
│ screens/<name>/<Name>ViewModel │ ← state + logic, exposes LiveData
├──────────────────────────────────────────────┤
│ core/ViewModelFactory │ ← injects IDatabaseService into ViewModels
├──────────────────────────────────────────────┤
│ services/ IDatabaseService → IUser/IFood/ICartService
│ services/impl/firestore | services/impl/rtdb
├──────────────────────────────────────────────┤
│ models/ User · Food · Cart │ ← plain Java objects (Identifiable)
└──────────────────────────────────────────────┘
| Layer | Responsibility |
|---|---|
| MainActivity | Hosts fragments, owns the toolbar, implements NavigationHost (navigateTo, goBack, title, back button) |
| core | BaseFragment (gets the NavigationHost, sets title/back button), ViewModelFactory (dependency injection) |
| screens | Fragment = View, ViewModel = state and calls to services |
| services | Async CRUD interfaces with callbacks; Firestore and Realtime DB implementations |
| models | Entities stored in the database |
| adapters | Display lists of carts, foods, users, and image-source options |
| utils | Input validation, image conversion/permissions, local session storage |
Data flow: Fragment calls a ViewModel method → ViewModel calls a service with a DatabaseCallback → callback updates MutableLiveData → Fragment's observer updates the UI.
Splash ──(logged in)──────────────────────────► Dashboard
│ │
└──(not logged in)──► Landing ├─► Add Food
├─► Login ──────────────┤
└─► Register ───────────┤
├─► Add Cart
├─► My Carts ──► Cart Details
├─► User Profile ──(sign out)──► Landing
└─► Admin (admins only)
├─► Users List ──► User Profile
├─► Food Items
└─► All Carts ──► Cart Details
- Create
screens/<name>/with<Name>Fragmentand<Name>ViewModel. - Make the ViewModel extend
ViewModeland take one constructor argument:IDatabaseService. - Make the Fragment extend
BaseFragment, implementgetTitle(), and overrideshouldShowBackButton()if it is a root screen. - Get the ViewModel with
new ViewModelProvider(this, new ViewModelFactory()).get(<Name>ViewModel.class). - Add a layout
res/layout/fragment_<name>.xml. - Open it from another screen with
navigationHost.navigateTo(new <Name>Fragment(), true).
No manifest change is needed — only MainActivity is declared.
Cloud Firestore is the default. To use Realtime Database, call this before anything uses the database (for example at the start of MainActivity.onCreate):
DatabaseService.setBackend(DatabaseService.DatabaseBackend.REALTIME_DATABASE);Both backends use the same paths/collections: users, foods, carts.
This project is licensed under the MIT License — see the LICENSE file for details.
Made with ❤️ by Gilyerm