Reward-E Architecture
Reward-E is an iOS app for families to track star rewards for kids. Parents award stars (each worth a configurable amount, e.g., 10 NOK) that kids can save or spend.
Tech Stack
| Component |
Technology |
| Frontend |
SwiftUI (iOS 17+) |
| Backend |
Firebase (Auth + Firestore) |
| Feedback |
CutiELink SDK |
| Build System |
XcodeGen |
Architecture Pattern
MVVM with a Service Layer and centralized app state:
flowchart TB
subgraph app["Reward-E iOS App"]
views["SwiftUI Views"]
appstate["AppState<br/>(ObservableObject)"]
services["Services"]
models["Models<br/>(Codable)"]
end
subgraph firebase["Firebase"]
auth["Firebase Auth<br/>(Apple Sign-In)"]
firestore["Cloud Firestore<br/>(Real-time sync)"]
end
views --> appstate
appstate --> services
services --> models
services --> auth
services --> firestore
| Layer |
Implementation |
Responsibility |
| Views |
SwiftUI Views |
UI rendering, user input |
| State |
AppState (@ObservableObject) |
Central app state, coordinates services |
| Services |
AuthService, FamilyService, GoalService |
Business logic, Firebase operations |
| Models |
User, Family, Child, Transaction |
Data structures (Codable) |
Project Structure
ios/
├── RewardE/
│ ├── RewardEApp.swift # App entry point, Firebase init
│ ├── ContentView.swift # Root view (onboarding vs main)
│ ├── Models/
│ │ ├── AppState.swift # Main app state
│ │ └── Models.swift # User, Family, Child, Transaction
│ ├── Services/
│ │ ├── AuthService.swift # Apple Sign-In + Firebase Auth
│ │ ├── FamilyService.swift # Firestore CRUD
│ │ ├── GoalService.swift # Savings goal management
│ │ └── ConnectionService.swift
│ └── Views/
│ ├── Components/ # Reusable UI components
│ └── ...
├── RewardE.xcodeproj
└── project.yml # XcodeGen config
Key Decisions
| Decision |
Rationale |
| Firebase over iCloud |
Real-time sync via Firestore listeners is simpler. Family sharing via invite codes is easier. |
| Parent-only MVP |
Simplifies auth flow. Kids view stars on parent's device. |
| Configurable star value |
Different families want different values (default 10 NOK). |
| Firestore transactions for spending |
Prevents race conditions where two simultaneous spend requests could exceed balance. |
| GoalService extracted from AppState |
Single Responsibility -- AppState was handling too many concerns. |
Firestore Data Model
flowchart TB
subgraph firestore["Cloud Firestore"]
families["families/{familyId}"]
children["families/{familyId}/children/{childId}"]
transactions["families/{familyId}/transactions/{txId}"]
users["users/{userId}"]
end
families --> children
families --> transactions
users --> families
- families -- Family settings (star value, currency, invite code)
- children -- Child profiles (name, avatar, star balance)
- transactions -- Star awards and spending history
- users -- User profiles linked to families
Firebase Configuration
| Property |
Value |
| Project ID |
reward-e-app |
| Region |
europe-west1 |
| Bundle ID |
no.invotek.RewardE |
| Auth |
Apple Sign-In |
| Persistence |
Enabled by default (offline-first) |
Firestore security rules are auto-deployed via GitHub Actions when firestore.rules is modified.