A multi-tenant mess (dining hall) management system built with Flutter and Firebase. The app streamlines daily operations for both mess administrators and members β from menu planning and attendance tracking to availability management, diet balance monitoring, and member approvals.
Platform: Flutter (Dart) + Firebase (Auth, Cloud Firestore, Cloud Functions)
- Phone number authentication with OTP verification
- Role-based access control β Admin & Client
- Auto-login via splash screen with role-based routing
- Firebase App Check integrated (Play Integrity & Debug Provider)
- New clients can skip mess selection during signup and join later
- Server-side signup & OTP rate-limiting via Cloud Functions
- Enhanced Local Testing: Auth debug settings enabled for seamless OTP testing manually.
| Page | Feature | Description |
|---|---|---|
| Admin Home Hub | Mess Selection | Centralized hub to manage up to 3 distinct messes per admin |
| Dashboard | Quick Actions | Access to menu, availability, members, attendance & notifications. Admins can also update mess names here. |
| Menu Management | Weekly Templates | Set/update a recurring 7-day weekly menu template (MonβSun) |
| Availability List | Meal Tracking | View available clients for each meal; generate attendance records |
| Members Panel | Member Mgmt | View all members, approve/remove, manage diet balances |
| Client Detail | Diet Allocation | Allocate diets to individual members (sends notification) |
| Notifications | Request Handling | Process approval & delete requests |
| Attendance | Record Keeping | Record & view meal attendance logs |
| Page | Feature | Description |
|---|---|---|
| Home Hub | Central Landing | Shows joined mess, available messes to join, profile & notifications |
| Mess Dashboard | Mess View | Diet counter, today's dynamic menu, "View Full Week" animated bottom sheet |
| Availability | Meal Toggles | Toggle ON/OFF for meals, plus new Specific Meal Permanent Off checkboxes (Morning/Evening) |
| Notifications | Activity Feed | Diet allocation alerts, removal requests (accept/reject), status updates |
| Profile | Account Mgmt | View profile, change password, change phone number, logout |
- Create a Mess β Admins create a new mess group
- Join a Mess β Clients browse messes from the Home Hub and send join requests
- Soft Removal β Admin removal clears mess association; client retains account and can rejoin
The entire UI follows a custom dark theme called "Midnight Feast", featuring:
| Token | Hex | Usage |
|---|---|---|
| Scaffold Dark | #0F0F1A |
Primary background |
| Surface Dark | #1A1A2E |
Card / panel backgrounds |
| Surface Light | #252540 |
Input fields / elevated surfaces |
| Accent Orange | #FF6B35 |
Primary actions, buttons, CTA |
| Accent Teal | #00D9A6 |
Success states, secondary actions |
| Accent Rose | #FF4D6D |
Errors, danger states |
| Accent Amber | #FFB347 |
Warnings |
| Accent Blue | #4DA8FF |
Informational states |
- Glassmorphism β Frosted-glass cards with
BackdropFilterblur, translucent backgrounds, and subtle borders - Gradient Accents β Multi-color gradient buttons and icon containers (OrangeβRose, TealβCyan, BlueβViolet, AmberβOrange)
- Micro-Animations β Staggered list entrance animations, press-scale feedback on cards, shimmer loading placeholders, and smooth page transitions (fade + slide)
- Modern Typography β
Poppinsfor headings,Interfor body text (via Google Fonts) - Consistent Spacing β 20px card padding, 16px border radius on inputs, 20px border radius on cards
| Widget | Description |
|---|---|
GlassCard |
Frosted-glass container with backdrop blur, press-scale animation, and configurable border/background |
GradientScaffold |
Full-screen scaffold wrapped in the scaffoldGradient for consistent backgrounds |
AnimatedListItem |
Staggered fade-in + slide-up entrance animation for list items |
ShimmerLoading |
Pulsing shimmer placeholder during data loading |
StatusBadge |
Colored pill badge with icon for status indicators (success/warning/danger/info) |
CustomButton |
Gradient button with loading state, icon support, and glow shadow |
CustomTextField |
Themed text input with icon prefix, validation, and focus animations |
![]() Splash Screen |
![]() Login |
![]() Sign Up |
![]() Profile |
![]() Update Name |
![]() Update Password |
![]() Update Phone |
![]() Admin Home Hub |
![]() Dashboard |
![]() Menu Management |
![]() Mess Name Update |
![]() Members |
![]() Pending Requests |
![]() Diet Allocation |
![]() Notifications |
![]() Attendance |
![]() Attendance Records |
![]() Availability List |
![]() Availability Details |
![]() Home Hub |
![]() Mess Dashboard |
![]() Weekly Menu |
![]() Notifications |
![]() Availability Status |
![]() Recurring Meal-Off |
![]() Permanent Off |
smart_mess_app/
β
βββ android/ # Android platform files
βββ ios/ # iOS platform files
βββ web/ | macos/ | windows/ | linux/ # Other platform targets
β
βββ assets/
β βββ icons/
β β βββ Mess_icon.png # App icon asset
β βββ UI_visuals/ # App screenshots for README
β
βββ functions/
β βββ index.js # Firebase Cloud Functions
β βββ processDietDeductions # Scheduled diet deduction (every 30 min)
β βββ createUserProfile # Server-side signup with rate limiting
β βββ reserveOtpRequest # OTP rate limiting per device
β
βββ firestore.rules # Firestore security rules
βββ firestore.indexes.json # Composite index definitions
βββ firebase.json # Firebase project configuration
β
βββ lib/
β βββ main.dart # App entry point (Firebase init)
β βββ app.dart # MaterialApp configuration (dark theme)
β β
β βββ core/
β β βββ constants/
β β β βββ app_colors.dart # "Midnight Feast" color palette + gradients
β β β βββ app_decorations.dart # Glass, gradient & accent box decorations
β β β βββ app_text_styles.dart # Typography tokens (Poppins + Inter)
β β β βββ app_strings.dart # Static strings
β β β βββ enums.dart # UserRole, MealType, NotificationType, etc.
β β β
β β βββ theme/
β β β βββ app_theme.dart # Full Material 3 dark theme definition
β β β
β β βββ utils/
β β β βββ validators.dart # Input validation
β β β βββ date_utils.dart # Date formatting & comparison helpers
β β β
β β βββ services/
β β β βββ auth_service.dart # Phone auth + OTP + password linking
β β β βββ firestore_service.dart # Firestore CRUD + streams
β β β βββ notification_service.dart # Create notifications in Firestore
β β β βββ diet_deduction_service.dart # Client-side diet deduction logic
β β β βββ device_id_service.dart # Persistent device ID for rate limiting
β β β
β β βββ routes/
β β βββ app_routes.dart # Route constants + animated route generator
β β
β βββ models/
β β βββ mess_model.dart # Mess group data
β β βββ user_model.dart # User profile + role + mess info
β β βββ diet_balance_model.dart # Total & remaining diets
β β βββ availability_model.dart # Per-meal availability status
β β βββ attendance_model.dart # Attendance record
β β βββ notification_model.dart # Notification with type, status, message
β β
β βββ repositories/ # Data access layer (abstract interfaces)
β β βββ auth_repository.dart
β β βββ user_repository.dart
β β βββ mess_repository.dart
β β βββ diet_repository.dart
β β βββ menu_repository.dart
β β βββ availability_repository.dart
β β βββ attendance_repository.dart
β β βββ notification_repository.dart
β β
β βββ features/
β βββ auth/
β β βββ splash/ # Splash β auto-route by role
β β βββ login/ # Phone login (controller + screen)
β β βββ signup/ # Registration + OTP
β β βββ otp/ # OTP verification screen
β β βββ create_mess/ # Admin: create new mess
β β βββ select_mess/ # Legacy: join mess (now via Home Hub)
β β
β βββ client/
β β βββ home/ # β
Home Hub β central landing page
β β βββ dashboard/ # Mess-specific: diet counter, menu, status
β β βββ availability/ # Meal availability toggles + calendar
β β βββ notifications/ # Notification feed with actions
β β βββ profile/ # Profile, change password, change phone
β β
β βββ admin/
β β βββ home/ # β
Admin Home Hub (manage multiple messes)
β β βββ dashboard/ # Admin dashboard with quick action cards
β β βββ menu/ # Set weekly menus (controller + screen)
β β βββ availability_list/ # View available members per meal
β β βββ attendance/ # Record & view attendance
β β βββ members/ # Member list + client detail + diet allocation
β β βββ notifications/ # Process approval/delete requests
β β
β βββ shared_widgets/
β βββ glass_card.dart # Glassmorphism card with blur + press feedback
β βββ gradient_scaffold.dart # Gradient-wrapped scaffold
β βββ animated_list_item.dart # Staggered list entrance animation
β βββ shimmer_loading.dart # Shimmer loading placeholder
β βββ status_badge.dart # Colored status pill badge
β βββ custom_button.dart # Gradient button with loading state
β βββ custom_text_field.dart # Themed input with validation
β
βββ pubspec.yaml # Dependencies
βββ README.md
| Layer | Technology |
|---|---|
| Framework | Flutter (Dart SDK ^3.10.8, Material 3) |
| Backend | Firebase (Auth + Cloud Firestore + Cloud Functions v2) |
| Security | Firebase App Check (Play Integrity + Debug Provider) |
| Auth | Firebase Phone Authentication (OTP) |
| State Management | Provider |
| Serverless | Firebase Cloud Functions (Node.js) β diet deduction, signup & OTP rate-limiting |
| Typography | Google Fonts (Poppins + Inter) |
| Animations | flutter_animate (shimmer, staggered lists, micro-interactions) |
| Calendar | table_calendar |
| Local Storage | shared_preferences |
| Utilities | intl (date formatting), uuid (device ID generation) |
The functions/ directory contains Firebase Cloud Functions v2 deployed to asia-south1:
| Function | Trigger | Description |
|---|---|---|
processDietDeductions |
Scheduled (every 30 min) | Processes meal-time diet deductions for all approved clients. Uses Firestore transactions and idempotent deduction markers (dietDeductionRuns) to prevent double-processing. |
createUserProfile |
Callable (onCall) | Server-side signup β validates auth, checks for duplicate accounts, enforces hourly signup rate limit (20/hour), and creates the user document. |
reserveOtpRequest |
Callable (onCall) | OTP rate limiting β tracks OTP requests per device ID (2/hour max) to prevent abuse. |
| Field | Type | Description |
|---|---|---|
uid |
string | User reference |
messId |
string | Mess reference |
date |
string | YYYY-MM-DD |
meal |
string | MORNING | EVENING |
deducted |
boolean | Whether a diet was actually deducted |
skippedReason |
string (optional) | Why deduction was skipped (e.g. user_off, availability_off, no_remaining_diets) |
processedAt |
timestamp | Processing time |
| Field | Type | Description |
|---|---|---|
deviceId |
string | UUID generated per device |
phoneNumber |
string | Requesting phone number |
createdAt |
timestamp | Request time |
All data is scoped by messId to ensure multi-tenant isolation.
| Field | Type | Description |
|---|---|---|
messName |
string | Unique name per admin |
createdBy |
uid | Admin who created it |
createdAt |
timestamp | Creation time |
| Field | Type | Description |
|---|---|---|
name |
string | Display name |
contactNumber |
string | Phone number |
role |
"ADMIN" | "CLIENT" |
User role |
messId |
string | null | Associated mess (null if not joined) |
approved |
boolean | Admin approval status |
permanentOff |
boolean | Permanently opt out of meals |
morningOff |
boolean | Morning meal opt-out |
eveningOff |
boolean | Evening meal opt-out |
createdAt |
timestamp | Registration time |
| Field | Type | Description |
|---|---|---|
totalDiets |
number | Total allocated diets |
remainingDiets |
number | Remaining (never < 0) |
lastUpdated |
timestamp | Last modification time |
| Field | Type | Description |
|---|---|---|
1 to 7 |
Map | Weekday maps (1=Mon, 7=Sun). Example: {"morning": "...", "evening": "..."} |
updatedBy |
uid | Admin who last updated |
updatedAt |
timestamp | Update time |
| Field | Type | Description |
|---|---|---|
uid |
string | User reference |
messId |
string | Mess reference |
date |
string | YYYY-MM-DD |
meal |
"MORNING" | "EVENING" |
Meal type |
status |
"ON" | "OFF" |
Availability |
locked |
boolean | Past cutoff = locked |
| Field | Type | Description |
|---|---|---|
messId |
string | Mess reference |
type |
"APPROVAL_REQUEST" | "DELETE_REQUEST" | "DIET_ALLOCATED" | "ACCOUNT_DELETED" |
Notification type |
fromUid / toUid |
uid | Sender / receiver |
status |
"PENDING" | "ACCEPTED" | "REJECTED" |
Current status |
message |
string (optional) | Human-readable detail (e.g. "30 diets added") |
createdAt |
timestamp | Request time |
| Field | Type | Description |
|---|---|---|
messId |
string | Mess reference |
date |
string | YYYY-MM-DD |
meal |
string | Meal type |
records/{uid}.present |
boolean | Attendance status |
π Retention rule: Only the latest 3 attendance documents per mess are retained.
| Collection | Fields | Order |
|---|---|---|
notifications |
toUid (Asc) + createdAt (Desc) |
Client notifications query |
notifications |
toUid (Asc) + status (Asc) + createdAt (Desc) |
Admin notifications query |
Create these indexes via the Firebase Console or by clicking the link in the debug console error. Index definitions are also available in
firestore.indexes.json.
Signup β OTP Verification β Login Page
Login β Splash β Route by Role
βββ Admin (no mess) β Create Mess β Login
βββ Admin (has mess) β Admin Dashboard
βββ Client (any) β Client Home Hub
Client Home Hub
βββ Has Mess + Approved β Tap to open Mess Dashboard
βββ Has Mess + Pending β Shows "Waiting for approval"
βββ No Mess β Browse & join from available list
βββ Notifications icon β Notification feed
βββ Profile icon β Profile management
| Type | Trigger | Displayed To | Actions |
|---|---|---|---|
APPROVAL_REQUEST |
Client joins mess | Admin | Approve / Reject |
DIET_ALLOCATED |
Admin adds diets | Client | Informational (shows amount) |
DELETE_REQUEST |
Admin removes client (diet > 0) | Client | Accept / Reject |
ACCOUNT_DELETED |
Admin removes client (diet = 0) | Client | Informational |
Admin clicks Delete
βββ Client has 0 remaining diets
β βββ Send ACCOUNT_DELETED notification
β βββ Clear messId & approved (soft-delete)
β βββ Delete dietBalances
β
βββ Client has remaining diets > 0
βββ Send DELETE_REQUEST notification
βββ Client decides:
βββ Accept β Clear messId, delete dietBalances β Home Hub
βββ Reject β Stay in mess
graph TD
A[Splash Screen] -->|Not Authenticated| B[Login Page]
A -->|Authenticated| C{Fetch Role}
B --> D[Sign Up]
D --> E[OTP Verification]
E --> B
C -->|Admin - no mess| F[Create Mess]
C -->|Admin - has mess| G[Admin Dashboard]
C -->|Client| H[Client Home Hub]
F --> B
H -->|Has mess + approved| I[Client Mess Dashboard]
H -->|No mess| J[Browse & Join Mess]
J -->|Join request sent| H
G --> K[Menu / Members / Attendance / Notifications]
K -->|Delete member diet=0| L[Soft-delete β Client returns to Home Hub]
K -->|Delete member diet>0| M[Delete Request β Client Accept/Reject]
K -->|Allocate diet| N[Diet Notification β Client]
For each meal, a diet is deducted if all conditions are met:
permanentOff == falsemealOff == false(morningOff / eveningOff)availability.status != "OFF"remainingDiets > 0
β‘ Deductions are processed server-side via the
processDietDeductionsCloud Function (runs every 30 minutes). Each deduction is tracked with an idempotent marker document indietDeductionRunsto guarantee exactly-once processing.
| Meal | Cutoff | After Cutoff |
|---|---|---|
| Morning | 7:00 AM | Locked (no toggle) |
| Evening | 3:00 PM | Locked (no toggle) |
- Flutter SDK (>= 3.10.8)
- Firebase CLI
- Node.js (>= 18, for Cloud Functions)
- A Firebase project with Phone Auth, Cloud Firestore, and Cloud Functions enabled
-
Clone the repository
git clone https://github.com/osctoss/smart_mess_app.git cd smart_mess_app -
Configure Firebase
dart pub global activate flutterfire_cli flutterfire configure
- Enable Phone Authentication in Firebase Console
- Enable Cloud Firestore in Firebase Console
- Place
google-services.jsoninandroid/app/ - Place
GoogleService-Info.plistinios/Runner/
-
Install Flutter dependencies
flutter pub get
-
Install & deploy Cloud Functions
cd functions npm install firebase deploy --only functions -
Create Firestore composite indexes (see Indexes Required section)
firebase deploy --only firestore:indexes
-
Deploy Firestore security rules
firebase deploy --only firestore:rules
-
Run the app
flutter run
- All reads/writes are filtered by
messId - Clients cannot access data from other messes
- Only Admin can modify: weekly_menus, dietBalances, approvals, attendance
- Only Client can modify: their own availability & profile
- Notifications are scoped to sender (
fromUid) and receiver (toUid)
| File | Reason |
|---|---|
lib/firebase_options.dart |
Firebase API keys |
android/app/google-services.json |
Android Firebase config |
ios/Runner/GoogleService-Info.plist |
iOS Firebase config |
.env / .env.* |
Environment variables |
*.jks / *.keystore / key.properties |
Signing keys |
β οΈ Each developer must generate their own Firebase config files usingflutterfire configure.
- β No negative diet balance
- β No cross-mess data access
- β Only 3 attendance logs retained per mess
- β Approval required before client can access mess dashboard
- β Permanent OFF overrides manual meal toggles
- β Time-restricted availability edits enforced
- β Soft-delete on member removal β clients can rejoin after being removed
- β Real-time notifications for diet allocation, removal, and approvals
- β Idempotent diet deductions β no double-processing via Cloud Functions
- β Server-side signup & OTP rate-limiting to prevent abuse
Author: Manish Patel (Osctoss)
Built with β€οΈ using Flutter & Firebase

























