Frischy App Case Study: Building a Flutter Food Delivery App End-to-End
How Fynx built Frischy — a cross-platform iOS and Android fresh food and grocery commerce app using Flutter, Firebase, and SQLite — from architecture to App Store submission.
When Frischy came to us, they had a clear product vision: bring fresh seafood, meat, and grocery delivery online for customers in Kerala, India. What they needed was a mobile app that felt native, handled the complexity of a real food commerce business, and shipped to both iOS and Android without doubling the build cost.
This is how we built it.
The Brief
Frischy's product requirements were more complex than a typical delivery app:
- Fresh food categories with subcategories — Seafood, Meat & Poultry, Fresh Store, Grocery, Ready to Cook, and Combo & Offer
- KG-type products that increment by 0.5 (not whole units), with cutting selections and cutting charges per item
- Real-time delivery availability based on the customer's GPS location — no browsing if you're outside the delivery zone
- Multiple authentication paths: email/password, phone OTP, Google, Facebook, and Apple Sign-In
- A checkout that stacks four discount mechanisms: category coupons, delivery coupons, wallet balance, and loyalty points
- Push notifications for order updates and promotions
- Crash reporting and analytics from day one
Building this as two separate native codebases — Swift for iOS, Kotlin for Android — would have doubled development time and long-term maintenance cost. Flutter was the obvious choice.
Why Flutter
Flutter compiles to native ARM code on both platforms from a single Dart codebase. The UI, state management, business logic, and networking layer are written once and run on both iOS and Android with no compromise in performance or fidelity.
For Frischy, this meant one team, one codebase, one deployment pipeline — and a roughly 40–50% reduction in total development cost compared to a native-only approach. Every feature update ships to both platforms simultaneously.
Architecture
We organised the app into clear, narrow layers:
- Presentation layer —
Screens/for page-level UI,Widgets/for reusable components. No networking or business logic in widgets. - State layer —
AppStateusing the Provider package. A single shared object manages the signed-in user, cart state, cart totals, delivery availability, and the active address. Any screen that needs this data reads fromAppState— no prop drilling. - Network layer —
AppApiwraps Dio with auth headers, locale headers, and base URL config.ApiImplconverts raw API responses into typed app models. - Local persistence — The cart is stored in SQLite via a dedicated
BagDBwrapper, so it survives app restarts. Secure tokens are stored in SharedPreferences. - Domain models — All JSON parsing happens at the API boundary. UI code works only with typed Dart models: products, carts, orders, addresses, coupons, users.
Authentication
We integrated four sign-in paths so customers could choose what felt familiar:
- Email and password — standard bearer token flow against the app backend
- Phone OTP via Firebase Authentication — the most common preference in South Asia
- Google Sign-In, Facebook Login, Apple Sign-In — all via the
SocialAccountclass, which exchanges social tokens for a backend session token
On every relaunch, AppState calls autoLogin() to restore the session silently. A token migration step runs first to move any legacy secure storage tokens into SharedPreferences on first launch.
Cart and Pricing Logic
The cart was one of the most involved parts of the build. Key rules we implemented:
- KG-type products (
qtyType == 3) increment and decrement in 0.5 steps. All other products use whole numbers. - Cutting selections — a single product can appear in the cart multiple times with different cutting options, each carrying its own cutting charge added at line-item level.
- Stock enforcement — before every quantity increase, the app checks stock. If the limit is exceeded, it throws "Out of stock" explicitly. No silent capping that surprises the customer at checkout.
- minSize floors — certain products have a minimum size that prevents decrementing below a floor rather than removing the item.
- SQLite persistence — the full cart state is saved locally and restored on relaunch, so customers never lose a partially built order.
Geofenced Delivery
Delivery availability is calculated in real-time using the Haversine formula against a fixed delivery centre coordinate. If the customer's location falls outside the 4.5 km radius, a NoDeliveryAvailable screen replaces the home experience entirely — no misleading browsing that ends in a checkout block.
Delivery charge and free-delivery threshold are loaded from the backend via a GET delsettings endpoint — not hardcoded — so Frischy can adjust pricing without requiring a new app release.
Checkout: Four Stacking Discounts
The checkout supports four discount mechanisms that can be combined in a single order:
- Category coupons — reduce the subtotal for products in a specific category
- Delivery coupons (
categoryId == -1) — knock off the delivery charge instead of the product subtotal - Wallet balance — draws down stored credit
- Loyalty points — convert at a server-configured rate (default: 10 points = ₹1), with a minimum redemption floor
The final POST order payload packages the cart, delivery metadata, coupon value, wallet balance used, and points redeemed into one request.
Firebase and Sentry
We integrated three Firebase services:
- Firebase Authentication — phone OTP sign-in
- Firebase Cloud Messaging (FCM) — push notifications for order status and promotions
- Firebase Analytics — event tracking for key user actions
Sentry handles crash reporting and unhandled exception monitoring in production. The client gets visibility into real crash rates and stack traces from day one, without building a custom error pipeline.
The Result
Frischy launched as a fully functional iOS and Android fresh food commerce app — one codebase, two stores, six product categories, four auth methods, and a checkout that handles the full complexity of a real delivery business.
If you're building a food delivery, grocery, or on-demand commerce app and want to understand the scope and cost, see our mobile app development service or book a free strategy call.
Frequently Asked Questions
How long does it take to build a food delivery app with Flutter?
A production-ready food delivery app with authentication, a product catalogue, cart, geofencing, and checkout typically takes 3–5 months for an experienced Flutter team. Apps with simpler scope (no subcategories, no wallet/points, basic auth only) can ship in 2–3 months. Complex apps with real-time driver tracking, multi-vendor support, or financial compliance requirements take 6–12 months.
What does a Flutter food delivery app cost in UAE?
For a mid-complexity app like Frischy — cross-platform (iOS + Android), Firebase integration, geofenced delivery, multi-auth, cart with custom pricing rules, and full checkout — expect AED 45,000–90,000 depending on design complexity and backend requirements. Simpler MVP-tier apps with basic browsing and ordering start around AED 25,000–40,000.
Why Flutter instead of native iOS and Android?
Flutter gives you one codebase that compiles to native ARM code on both platforms. For most food delivery and commerce apps, the performance is indistinguishable from native. The cost saving is roughly 40–50% compared to maintaining separate Swift (iOS) and Kotlin (Android) codebases. The only cases where native is clearly better are apps that need deep platform-specific hardware access or are highly CPU-intensive (3D games, real-time video processing).
How is delivery zone enforcement typically implemented in mobile apps?
The two common approaches are client-side calculation (Haversine formula against a fixed coordinate, as used in Frischy) and server-side validation (sending the user's coordinates to the backend, which checks against a delivery zone polygon). Client-side calculation is fast and works offline; server-side validation is more flexible for irregular delivery zones and prevents spoofing. For complex multi-zone apps, we recommend server-side validation.
Work with Fynx
Ready to grow your business?
We run the same playbooks for clients across UAE and MENA. Drop us a message and let's talk.
Talk to the team