Documentation
The definitive production & deployment guide for the NutriScan AI App.
1. Project Overview
Flutter 3.x.x
Cross-platform mobile framework powered by Dart.
Firebase
Handles Authentication, FireStore, Storage, and Configs.
Groq Deep AI
Lightning-fast AI inference for Llama-3 models.
Please note that this app requires external services to function in production:
- Firebase: Costs may apply based on usage (Blaze Plan).
- Groq AI: Requires a Groq API key (Usage-based pricing).
- Store Fees: Apple ($99/year) and Google ($25 one-time) developer fees are required for publishing.
2. Setup Guide
Welcome to NutriScan! To ensure a flawless deployment, please follow these steps chronologically. Do not skip around.
Step 1: Prerequisites & SDK
- Flutter SDK: Install Flutter (version 3.x.x) on your computer.
- IDE: Install Android Studio or VS Code with Flutter and Dart plugins.
- Extracting: Extract the downloaded CodeCanyon ZIP file. Open the inner
nutriscanflutter directory in your IDE. Do NOT open the root ZIP folder directly.
Step 2: Get Dependencies
Open your IDE terminal inside the project directory and run:
flutter clean
flutter pub get
Step 3: Change Package Name (Bundle ID) & App Assets
firebase_options.dart, google-services.json, and GoogleService-Info.plist must exactly match your app's Bundle ID.1. Automated Package Change: Use the automated tool to safely update com.example.nutriscan across the entire Android and iOS directories.
flutter pub run change_app_package_name:main com.yourcompany.yourapp
2. Verify Consistency: Ensure the new ID is reflected in:
android/app/build.gradle(namespace & applicationId)ios/Runner/Info.plist(bundle identifier)android/app/src/main/AndroidManifest.xml
- App Icon: Use your 1024x1024 high-resolution asset (e.g.,
assets/images/logo.jpg). We have updated the configuration to use this file for the app launcher icon. - SVG Assets: All custom UI illustrations (Login, Onboarding) are located in
assets/images/svg/. If you replace them, keep the same filenames or update matching paths in the Dart code. - Generate Assets: Run this command to automatically compile the icons:
# Generate Android/iOS icons flutter pub run flutter_launcher_icons
Step 4: Firebase Configuration (FlutterFire CLI)
If you change your Bundle ID after the initial setup, you MUST regenerate your Firebase configuration files using the FlutterFire CLI. This is the only way to guarantee consistency.
- Go to the Firebase Console and create a new project.
- Install/Verify Firebase CLI:
npm install -g firebase-tools - Log into Firebase:
firebase login - Activate/Update FlutterFire CLI:
dart pub global activate flutterfire_cli - Regenerate Config: Run this command in your project root whenever you change the package name:
flutterfire configure - Select your project, and check both
androidandios. This will updatelib/firebase_options.dart,google-services.json, andGoogleService-Info.plistwith your new Bundle ID automatically! - Authentication: Enable "Email/Password" and "Google" in the Firebase Console.
- Security Rules: Deploy the bundled security rules to protect your revenue:
firebase deploy --only firestore:rules --project your_project_id
Step 5: Groq AI Setup (Core Engine)
NutriScan analyzes food imagery using Groq's superfast infrastructure.
- Sign up at the Groq Console.
- Generate a new API Key. Save it securely for later injection.
Step 6: AdMob Monetization
NutriScan supports Smart Banners, Interstitials, Rewarded, and App Open ads. The frequency and limits are strictly regulated inside the codebase to incentivize users to purchase Premium.
- Create AdMob App: Create a new application in Google AdMob for both Android and iOS.
- Generate Ad Units: Create all four ad formats for both platforms.
- Update Ad Unit IDs: Open
lib/config/ads_config.dart. Replace the test IDs with your production IDs. - Update Native App IDs: Open
android/app/src/main/AndroidManifest.xmland update thecom.google.android.gms.ads.APPLICATION_IDmeta-data block. Also updateios/Runner/Info.plist. - Automatic Test Mode: We have implemented
kDebugModeinlib/config/ads_config.dart. This means test ads are automatically enabled during development and disabled in production builds. You do not need to manually toggle this flag!
Step 7: Store Setup (In-App Purchases)
To accept subscriptions securely, NutriScan delegates subscription handling entirely to Google Play and Apple App Store architectures.
- Set up a Google Play Console and Apple App Store Connect account.
- Create your two auto-renewable subscription packages in both stores.
- Use the product IDs
premium_monthlyandpremium_yearly, OR update the string mapping insidelib/config/app_config.dartto match whatever product IDs you created.
Step 8: Run Your App!
If you've followed every step correctly up to this point, your app is fully functional. Test the app using the following launch command to safely inject your Groq API key:
flutter run --dart-define=GROQ_API_KEY=gsk_your_real_key_here
3. Language & Translations
NutriScan supports 10+ major languages natively.
If you wish to change any translations or add a custom dialect, simply open lib/config/app_localizations.dart and adjust the mapped strings directly!
4. Coins & Plans
To adjust the Freemium balance and subscription conversion rates, the ad-to-coin ratio can be modified inside lib/config/ads_config.dart.
The premium logic is actively managed in lib/providers/payment/subscription_provider.dart
5. Android Release & App Signing
To publish your app to the Google Play Store, you must sign it with a release keystore. Follow these detailed steps to prepare your app for production. This ensures your app is secure and verifiable.
Step 1: Generate a Release Keystore
A keystore is a binary file that contains your private keys. IMPORTANT: Keep this file safe and never lose it. If you lose your keystore, you will never be able to update your app on the Google Play Store again.
Open your terminal/command prompt and run the following command:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
keytool -genkey -v -keystore %USERPROFILE%\upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
Step 2: Configure key.properties File
Create a plain text file named key.properties in the android/ directory (the project root's android folder). This file links your keystore to the build process.
storePassword=your_keystore_password
keyPassword=your_key_password
keyAlias=upload
storeFile=/Users/username/upload-keystore.jks
Property Definitions:
storePassword: The password you created for the keystore.keyPassword: The password you created for the specific key alias.keyAlias: The alias name used during generation (usuallyupload).storeFile: The absolute path to your.jksfile.
key.properties to your .gitignore file to avoid exposing your credentials in version control.Step 3: Build Gradle Configuration
The android/app/build.gradle.kts in this project is already pre-configured to read your key.properties file and sign the APK/AAB automatically. Here is the relevant configuration block for reference:
// 1. Loading the properties
val keystorePropertiesFile = rootProject.file("key.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
// 2. Defining the Signing Configuration
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String?
keyPassword = keystoreProperties["keyPassword"] as String?
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String?
}
}
buildTypes {
release {
// 3. Applying the Signing Configuration
signingConfig = if (keystorePropertiesFile.exists()) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
Step 4: Generate Release Build
Once the signing is configured, run the following command to generate your production-ready App Bundle (.aab):
flutter build appbundle --obfuscate --split-debug-info=./debug_info --dart-define=GROQ_API_KEY=your_production_key
The output file will be located at build/app/outputs/bundle/release/app-release.aab.
6. iOS Release
Open ios/Runner.xcworkspace in Xcode to update bundle ID mapping, device capabilities, and Apple Developer provisioning profiles.
Similar to Android, review Section 7 below to learn how to securely compile the `.ipa` package using Flutter's obfuscator suite.
7. Code Security & Obfuscation
1. Dart Obfuscation Flags (Mandatory)
Whenever you generate a release build, ensure you use the --obfuscate flag as detailed in Section 5 (Android Release).
This explicitly tells Flutter to scramble your code into random meaningless characters. Keep the generated debug_info folder safe on your local disk. It is required to de-obfuscate crash reports from production.
2. The Compile-Time Key Injection (`--dart-define`)
Never hardcode your real production Groq API key inside the Dart core files. Using the --dart-define parameter safely injects the API key at compile-time directly into binary, drastically mitigating the risk of reverse-engineering scrapers grabbing your keys.
3. Native Android Obfuscation (R8)
We have already pre-configured Native Android ProGuard configurations for you natively! The app utilizes isMinifyEnabled and isShrinkResources automatically during a release build. This guarantees the absolute security of the underlying AdMob bindings and standard Google Play Billing lifecycles.
8. Troubleshooting & Common Fixes
Encountering issues during setup or build? Most common problems are related to environment configuration. Here are the solutions to the most frequently reported issues.
1. Firebase & Google Login Issues
If Google Login fails or the app crashes on startup, check the following:
- SHA-1 Fingerprint: You MUST add both
debugandreleaseSHA-1 fingerprints from your machine to the Firebase Console. Without this, Google Login will returnerror 10or12500. - Package Name Mismatch: Ensure the
applicationIdinandroid/app/build.gradle.ktsexactly matches the one you registered in Firebase. - Google Services JSON: Ensure
google-services.jsonis inandroid/app/andGoogleService-Info.plistis inios/Runner/.
2. CocoaPods & iOS Build Errors
If you encounter pod: command not found, Error: CocoaPods not installed, or linking errors on macOS:
# 1. Reinstall CocoaPods
sudo gem install cocoapods
# 2. Reset the iOS build folder
cd ios
rm -rf Pods
rm Podfile.lock
pod install
cd ..
# 3. Clean and rebuild
flutter clean
flutter pub get
3. Gradle & Android Build Issues
If you see Gradle sync errors, "Task not found", or Java version conflicts:
# Clear Gradle and Flutter cache
cd android
./gradlew clean
cd ..
flutter clean
flutter pub get
Note: This app requires **Java 17**. Ensure your IDE (Android Studio) is configured to use JDK 17 for the Gradle process.
4. AdMob Ads Not Showing
- App ID Verification: Verify that the
com.google.android.gms.ads.APPLICATION_IDinAndroidManifest.xmlmatches your AdMob App ID. - App Review: New apps can take up to 48 hours to start serving production ads. Ensure your app is "Ready" in the AdMob console.
- Test Mode: Remember that test ads are automatically enabled in debug mode. If you see test ads, your configuration is correct.
5. Groq AI & API Errors
Common errors when analyzing food images:
- 401 Unauthorized: Your
GROQ_API_KEYis invalid or has not been injected via--dart-definecorrectly. - 429 Too Many Requests: You have hit the rate limit for the Llama-3 model on Groq's free tier. Consider upgrading your Groq plan.
Common Flutter Fixes
- Dependency Conflicts: Run
flutter pub upgrade --major-versionsif you encounter version mismatches. - Environment Check: Run
flutter doctor -vand ensure there are no red "X" marks for Android or iOS.
9. Release Notes & Changelog
Version 2.1.2 — April 2026 Latest
Platform & Security
- IAP Migration – Fully transitioned from Stripe APIs to Google/Apple Native In-App Purchases.
- Security Hardening – Implemented automatic AdMob test mode; Mandated secure logic via
--dart-defineand Dart Obfuscation. - Asset Optimization – Reorganized SVGs and replaced legacy icons with premium assets.
- Encrypted Caches – Subscriptions and tokens now use Flutter Secure Storage (AES).
- Rules Security – Implemented optimized Firestore security rules.
Features
- Context-Aware AI Coach – Enhanced AI analysis for 7-day food history mapping.
- AdMob Funnels – Fine-tuned ad-to-coin ratios to optimize premium conversions.
- Codebase Optimization – Refined repository by removing legacy modules and fixing async-gap issues.
Version 2.0.2 — February 2026
- Nutrient deficiency notification engines.
- Smart meal plan models leveraging rolling 14-day history loops.
- Auto-select localized AI schema overrides.
Version 1.0.0 — July 2025
- Initial CodeCanyon Baseline.
Need More Help?
If you have specific engineering issues or API concerns, reach out via WhatsApp.
💬 Message via WhatsApp