ChefAI documentation
Run it, point it at your own accounts, ship it under your own brand. Written against version 1.1.0 of the download you get on CodeCanyon.
- Version v1.1.0
- Updated Jul 2026
- Platform Flutter
- Stack Flutter · AI
On this page
Introduction
AI-powered recipe generator, weekly meal planner and calorie tracker built with Flutter. Complete source code for CodeCanyon buyers.
ChefAI is a full-featured Flutter mobile app that lets users generate AI-powered recipes from ingredients they already have, plan weekly meals, track calories and macros, and follow interactive step-by-step cooking mode — all powered by OpenAI or Google Gemini.
This package includes the complete Flutter source code, Firebase configuration, and all assets needed to publish on the App Store and Google Play under your own brand.
Key features
Tech stack
- Flutter 3.24
- Dart 3.5
- Riverpod 2
- Firebase
- OpenAI GPT-4o
- Gemini 3.5 Flash
- iOS and Android
Features
Requirements
Installation
- 01
Extract the source code
Unzip the downloaded package. You will find the Flutter project inside thechef-ai/folder. - 02
Install Flutter dependencies
Open a terminal in the project root and run:
terminalflutter pub get - 03
Generate code (freezed models and Riverpod)
This step is required whenever models change. Run:
terminalflutter pub run build_runner build --delete-conflicting-outputs - 04
Install iOS pods
Required for iOS builds only:
terminalcd ios && pod install && cd .. - 05
Complete Firebase setup (see next section)
The app will not run without Firebase configuration files.
flutter run to verify the app launches on a device or simulator.Firebase setup
ChefAI uses Firebase for authentication, Firestore database, Remote Config (API keys), push notifications, and analytics.
Create a Firebase project
- 01Sign in with a Google account and click Add project.
- 02
Register Android app
Package name:com.devsnack.chefai(change to your own ID). Downloadgoogle-services.jsonand place it inandroid/app/. - 03
Register iOS app
Bundle ID:com.devsnack.chefai(change to your own ID). DownloadGoogleService-Info.plistand place it inios/Runner/.
Enable Firebase services
In the Firebase Console, enable the following services under your project:
Apply Firestore security rules
In Firestore → Rules tab, paste the following:
// Firestore Security Rules — paste in Firebase Console → Firestore → Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
match /recipes/{recipeId} {
allow read: if request.auth != null &&
(resource.data.userId == request.auth.uid || resource.data.userId == null);
allow create: if request.auth != null &&
request.resource.data.userId == request.auth.uid;
allow update, delete: if request.auth != null &&
resource.data.userId == request.auth.uid;
}
match /mealPlans/{userId}/weeks/{weekId} {
allow read, write: if request.auth.uid == userId;
}
match /shoppingLists/{userId}/weeks/{weekId} {
allow read, write: if request.auth.uid == userId;
}
match /nutritionLogs/{userId}/days/{date} {
allow read, write: if request.auth.uid == userId;
}
}
}Remote Config and API keys
All API keys and feature flags are stored in Firebase Remote Config — never hardcoded in the app. This allows you to update keys without releasing a new app version.
Add Remote Config parameters
In Firebase Console → Remote Config → Add parameter:
sk-openai or geminiGetting API keys
- OpenAI: visit platform.openai.com → API Keys → Create new secret key. Make sure your account has Chat Completions access (requires a paid plan).
- Google Gemini: visit aistudio.google.com → API Keys → Create API key. Gemini 3.5 Flash / Flash-Lite are available on the free tier with rate limits.
RevenueCat (in-app purchases)
ChefAI uses RevenueCat to manage premium subscriptions across iOS and Android with a single integration.
- 01
Create a RevenueCat account
Go to app.revenuecat.com and create a new project named ChefAI. - 02
Add iOS and Android apps
Add your bundle ID for iOS and package name for Android. Copy the Public API Key for each platform. - 03
Create products in App Store Connect / Google Play
Create subscription products (e.g.chefai_premium_monthly,chefai_premium_yearly). Import them into RevenueCat. - 04
Update the app
Open
lib/data/services/revenue_cat_service.dartand replace the placeholder API keys with your RevenueCat public API keys.revenue_cat_service.dart// lib/data/services/revenue_cat_service.dart await Purchases.configure( PurchasesConfiguration('your_revenuecat_public_key') );
AdMob setup
- 01
Create an AdMob account
Go to admob.google.com. Create your account and add an app for both iOS and Android. - 02
Create ad units
Create a Banner ad unit and an Interstitial ad unit. Copy the Ad Unit IDs. - 03
Add App IDs to native config
The AdMob App ID (not ad unit ID) must be added to native files:
Android —
android/app/src/main/AndroidManifest.xmlAndroidManifest.xml<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX"/>iOS —
ios/Runner/Info.plistInfo.plist<key>GADApplicationIdentifier</key> <string>ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX</string> - 04
Set ad unit IDs in Remote Config
Addadmob_banner_idandadmob_interstitial_idin Firebase Remote Config (see Remote Config section above).
Branding and colors
All colors are centralized in lib/core/constants/app_colors.dart. Never hardcode colors in widgets — always use AppColors constants.
Change the primary color
The default accent is Saffron Orange (#F97316). To rebrand with a different color, update these two values in app_colors.dart:
static const primary = Color(0xFFF97316); // ← change this
static const primaryLight = Color(0xFFFB923C); // ← and this (lighter shade)
static const primaryTint = Color(0xFFFED7AA); // ← background tintChange app icon
Replace the icon assets:
- Android: Replace files in
android/app/src/main/res/mipmap-*/ - iOS: Replace assets in
ios/Runner/Assets.xcassets/AppIcon.appiconset/
Or use the flutter_launcher_icons package for automated generation from a single source image.
Change app name
android:label="ChefAI"CFBundleDisplayName and CFBundleNameChange bundle / package ID
android/app/build.gradle → applicationIdTypography and copy
ChefAI uses Montserrat loaded via the google_fonts package. No font files need to be bundled — they are downloaded automatically on first launch and then cached.
Typography scale
To change the font family, replace GoogleFonts.montserrat() with any other google_fonts font in lib/core/theme/app_theme.dart.
Strings and copy
All user-facing text is stored in lib/core/constants/app_strings.dart. To translate or rebrand the app copy, edit only this file — do not change strings directly in widgets.
The app is English only in v1. Multi-language support is planned for v2.
Architecture
Folder structure
lib/
├── core/
│ ├── constants/ ← colors, strings, sizes, prompts
│ ├── enums/ ← AIProvider, MealType, DietaryPreference…
│ ├── theme/ ← light & dark themes
│ ├── router/ ← GoRouter routes + auth redirect
│ └── utils/ ← NutritionCalculator, ServingScaler…
│
├── data/
│ ├── models/ ← freezed models (Recipe, MealPlan…)
│ ├── repositories/ ← Firestore read/write logic
│ └── services/
│ ├── ai/ ← RecipeAIService + OpenAI + Gemini + Factory
│ ├── remote_config_service.dart
│ ├── revenue_cat_service.dart
│ └── admob_service.dart
│
├── presentation/
│ ├── providers/ ← Riverpod providers (auth, recipe, meal plan…)
│ ├── screens/ ← one folder per feature / screen
│ └── widgets/ ← common, recipe, nutrition, meal_plan, cooking
│
└── main.dartState management
ChefAI uses Riverpod 2 with code generation. All business logic lives in lib/presentation/providers/. Key providers:
setState for business logic. Never call AI APIs directly from a screen. Always go through a Riverpod provider.Navigation
ChefAI uses GoRouter with a shell route for the bottom navigation bar. Auth-guard redirects unauthenticated users to /login and unboarded users to /onboarding.
// Always navigate with GoRouter — never use Navigator.push
context.go('/home'); // replace stack
context.push('/recipe/123'); // push on stack
context.pop(); // go backAI services
AI calls go through an abstract interface RecipeAIService. Screens and providers never know which AI provider is active — the factory picks the right implementation based on Remote Config.
Switching AI provider
Change the default_ai_provider value in Firebase Remote Config to openai or gemini. The change takes effect on the next app fetch (within 1 hour) — no app update needed.
AI methods
Adding a new AI provider
- 01Create a new class implementing
RecipeAIService - 02Add the provider to
AIProviderenum - 03Add a case to
AIServiceFactory.create() - 04Add the API key to Remote Config
Data models
All models use freezed for immutability and JSON serialization. Never write models by hand.
After any model change, always regenerate:
flutter pub run build_runner build --delete-conflicting-outputsFree tier limits
Limits are enforced in providers, not screens. All values come from Remote Config so you can adjust them without an app update.
Build and release
Build commands
# Install dependencies
flutter pub get
# Regenerate code after model changes
flutter pub run build_runner build --delete-conflicting-outputs
# Format code
dart format lib/
# Static analysis (must be zero issues)
flutter analyze
# Run in debug mode
flutter run
# Build release APK
flutter build apk --release
# Build release App Bundle (Google Play)
flutter build appbundle --release
# Build release iOS (requires macOS + Xcode)
flutter build ios --releaseAndroid release
- 01
Generate a keystore
terminalkeytool -genkey -v -keystore ~/upload-keystore.jks -alias upload -keyalg RSA -keysize 2048 -validity 10000 - 02
Configure signing
Createandroid/key.propertieswith your keystore path, alias, and passwords. Reference it inandroid/app/build.gradle. - 03
Update version
Inpubspec.yaml, setversion: 1.0.0+1(name+build number). - 04
Build App Bundle
flutter build appbundle --release→ uploadbuild/app/outputs/bundle/release/app-release.aabto Google Play.
key.properties or your .jks keystore file to git. Add both to .gitignore. Losing the keystore means you cannot update your app.iOS release
- 01
Open in Xcode
Openios/Runner.xcworkspace(not.xcodeproj) in Xcode. - 02
Set team and bundle ID
In Runner → Signing and Capabilities, select your Apple Developer Team and set the Bundle Identifier to your own ID. - 03
Add Sign in with Apple capability
Click + Capability → add Sign In with Apple. - 04
Archive and upload
Product → Archive → Distribute App → App Store Connect → Upload.
Podfile and project.pbxproj.Pre-launch checklist
- Change bundle ID / package name from
com.devsnack.chefaito your own - Place
google-services.jsoninandroid/app/ - Place
GoogleService-Info.plistinios/Runner/ - Enable Firebase Auth (Email, Google, Apple)
- Apply Firestore security rules
- Add all Remote Config parameters (API keys, limits, AdMob IDs)
- Add AdMob App ID to
AndroidManifest.xmlandInfo.plist - Configure RevenueCat and update API key in
revenue_cat_service.dart - Update app name in
AndroidManifest.xmlandInfo.plist - Replace app icon assets
- Run
flutter analyze— zero issues - Test on a real iOS device and Android device
- Test purchase flow in sandbox / test environment
- Test AdMob ads are loading
- Verify dark mode on all screens
FAQ and troubleshooting
google-services.json and GoogleService-Info.plist are in the correct locations and that firebase_options.dart matches your project.openai_api_key (or gemini_api_key) is set in Firebase Remote Config and that the key has sufficient credits/quota.flutter pub run build_runner clean then flutter pub run build_runner build --delete-conflicting-outputs.cd ios && pod deintegrate && pod install. Make sure CocoaPods is up to date: sudo gem install cocoapods.openai_model, openai_model_fast, gemini_model, or gemini_model_fast in Firebase Remote Config. The “fast” models are used for nutrition lookups and ingredient substitutions; the standard models are used for recipe and meal plan generation. Leaving a value blank falls back to the built-in default.Note: AI providers retire models over time. If generation suddenly starts failing, check that your configured model is still available — that is the most common cause. Also note that OpenAI’s GPT-5 family renamed max_tokens to max_completion_tokens, so switching to one of those models also requires updating the request body in _chat() in lib/data/services/ai/openai_recipe_service.dart.pubspec.yaml, and remove references from providers. Both are optional integrations.Changelog
Every version published so far. Updates are free for the life of the item.
Version 1.2.0 · August 2026
- Smart shopping list — build a grocery list from the weekly meal plan. Duplicate ingredients are merged across recipes, grouped by supermarket aisle, with tick-off state saved to Firestore, manual items, and plain-text sharing.
- AI model IDs moved to Remote Config (
openai_model,gemini_model, and their_fastvariants) — change models without an app update when a provider retires one. - Default Gemini models updated to the current generation.
- Editable profile (
/profile/edit) — diet, allergies, cuisines, calorie and macro goals, household size, cooking skill, and measurement units, with a BMR/TDEE calorie calculator. - Paywall now loads real RevenueCat offerings and purchases the selected package.
- Request timeouts and detailed error logging added to both AI services; token budgets now scale with the requested recipe count.
- Fixes: cooking timer notifications now initialize and fire; recipe ratings and cook counts persist for unsaved recipes; the logging streak increments; fiber is tracked per logged meal; scaled servings carry into cooking mode.
shoppingLists collection, and the shopping list will fail with permission-denied without it. Then run flutter pub run build_runner build --delete-conflicting-outputs for the new models.Version 1.1.0 · July 2026
- Manual meal logging to any meal section.
- AI nutrition lookup surfaced in the tracker.
- Shared AI service provider used by both recipe generation and nutrition lookup.
Version 1.0.0 · March 2026
- Initial release — all screens, dual AI providers, RevenueCat + AdMob monetization, full dark mode, step-by-step cooking mode with wakelock and timers.
Support and licensing
We’re happy to help with installation, configuration, and customization questions. Typical response time is within 24 hours on business days.
flutter --version), and a description of the issue with any error messages.What support covers
- Six months of support from purchase, extendable at checkout
- Support covers bugs in the template and questions about how it is put together
- It does not cover custom feature work, third-party API changes or store review outcomes
- The Regular licence covers one free end product. Charging users for the app itself needs the Extended licence