Documentation

The definitive production & deployment guide for the NutriScan AI App.

1. Project Overview

Frontend

Flutter 3.x.x

Cross-platform mobile framework powered by Dart.

Backend

Firebase

Handles Authentication, FireStore, Storage, and Configs.

AI Engine

Groq Deep AI

Lightning-fast AI inference for Llama-3 models.

⚠️
External Service Fees:
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 nutriscan flutter 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

⚠️
CRITICAL: You MUST change your package name before connecting to Firebase. The Bundle ID in the 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.

  1. Go to the Firebase Console and create a new project.
  2. Install/Verify Firebase CLI: npm install -g firebase-tools
  3. Log into Firebase: firebase login
  4. Activate/Update FlutterFire CLI: dart pub global activate flutterfire_cli
  5. Regenerate Config: Run this command in your project root whenever you change the package name:
    flutterfire configure
  6. Select your project, and check both android and ios. This will update lib/firebase_options.dart, google-services.json, and GoogleService-Info.plist with your new Bundle ID automatically!
  7. Authentication: Enable "Email/Password" and "Google" in the Firebase Console.
  8. 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.

  1. Sign up at the Groq Console.
  2. 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.

  1. Create AdMob App: Create a new application in Google AdMob for both Android and iOS.
  2. Generate Ad Units: Create all four ad formats for both platforms.
  3. Update Ad Unit IDs: Open lib/config/ads_config.dart. Replace the test IDs with your production IDs.
  4. Update Native App IDs: Open android/app/src/main/AndroidManifest.xml and update the com.google.android.gms.ads.APPLICATION_ID meta-data block. Also update ios/Runner/Info.plist.
  5. Automatic Test Mode: We have implemented kDebugMode in lib/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.

  1. Set up a Google Play Console and Apple App Store Connect account.
  2. Create your two auto-renewable subscription packages in both stores.
  3. Use the product IDs premium_monthly and premium_yearly, OR update the string mapping inside lib/config/app_config.dart to 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:

Terminal
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

🔒
Subscription and coin states are internally protected by Flutter Secure Storage (Local AES Encryption) to severely mitigate client-side hacking.

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:

Terminal (macOS / Linux)
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
Terminal (Windows)
keytool -genkey -v -keystore %USERPROFILE%\upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
💡
After running the command, you will be prompted for passwords and your organization details. Write down these passwords as you will need them in the next step.

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.

android/key.properties
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 (usually upload).
  • storeFile: The absolute path to your .jks file.
⚠️
Security Recommendation: Add 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:

android/app/build.gradle.kts
// 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

⚠️
Critical Protection: By default, compiled Dart code contains exposed class names, method structures, and plain-text string constants. You MUST use obfuscation to protect your API Keys and In-App Purchase architectures.

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 debug and release SHA-1 fingerprints from your machine to the Firebase Console. Without this, Google Login will return error 10 or 12500.
  • Package Name Mismatch: Ensure the applicationId in android/app/build.gradle.kts exactly matches the one you registered in Firebase.
  • Google Services JSON: Ensure google-services.json is in android/app/ and GoogleService-Info.plist is in ios/Runner/.

2. CocoaPods & iOS Build Errors

If you encounter pod: command not found, Error: CocoaPods not installed, or linking errors on macOS:

Terminal
# 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:

Terminal
# 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_ID in AndroidManifest.xml matches 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_KEY is invalid or has not been injected via --dart-define correctly.
  • 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-versions if you encounter version mismatches.
  • Environment Check: Run flutter doctor -v and 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-define and 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