eSellify Documentation

Complete setup and deployment guide for your multi-platform e-classified application.

v1.3 - Flutter + Firebase
💻
Platform
Android, iOS & Web
🔧
Framework
Flutter + Firebase
📧
Support Email
📞
WhatsApp

Key Features

📱

Multi-Platform

Build for Android, iOS, and Web from a single Flutter codebase.

🔐

Authentication

Phone, Google, and Apple sign-in powered by Firebase Authentication.

🛒

Shopping Cart

Full-featured cart with quantity management, coupons, and checkout flow.

🔔

Push Notifications

Real-time notifications via Firebase Cloud Messaging (FCM) on all platforms.

Admin Panel

Full-featured Flutter web admin dashboard for managing products, orders, and users.

💳

Payment Gateway

Multiple payment integrations including Stripe, Razorpay, PayPal, and COD.

What's Included

Live Demo

⚙️
Admin Panel
🌐
Landing Page
🤖
Android App
🍎
iOS App
📝 Demo Credentials
Platform Email Password
Admin Panel admin@esellify.com 123456

Before starting the setup, make sure you have the following tools and accounts ready.

Required Software

Software Version Purpose
Flutter SDK Latest Stable Framework for building the app
Dart SDK Bundled with Flutter Programming language for Flutter
Android Studio Latest IDE & Android SDK/Emulator
Xcode (macOS only) Latest iOS development & simulator
Firebase CLI Latest Deploy and manage Firebase services
Git Latest Version control
VS Code / Android Studio Latest Code editor with Flutter/Dart plugins

Required Accounts

Important:
  • Some Firebase features (phone authentication, etc.) require the Blaze plan (pay-as-you-go). The free Spark plan has limitations.
  • Ensure your system meets Flutter's minimum system requirements for your OS.

Follow these steps in order for a smooth setup experience. Each step links to the detailed section below.

Important — please read first:

What you received is the Flutter source code, not a ready-to-upload website. Uploading the source code directly to your hosting will NOT work. You must:

  1. Set up Firebase first — create the project, connect it to the apps, and add the configuration files. The apps will not run or build correctly until Firebase is configured.
  2. Generate a build — for the web (Admin Panel / Customer Web) run flutter build web --release; for Android/iOS build the APK/AAB or iOS archive.
  3. Upload only the build output — for web, upload the generated build/web folder contents to your server (or deploy with Firebase Hosting). Never upload the raw lib/ source to a web server.
Estimated Setup Time

Following this guide carefully, the complete setup typically takes 1-2 hours depending on your familiarity with Flutter and Firebase.

To set up Flutter on both Windows and macOS, follow these step-by-step instructions.

Setting Up Flutter on Windows

System Requirements
Download Flutter SDK
Add Flutter to System Path
Verify Installation
flutter doctor
Install Android Studio
Set Up an Android Emulator
Final Setup Check
flutter doctor

Setting Up Flutter on macOS

System Requirements
Download Flutter SDK
Add Flutter to PATH
export PATH="$PATH:$HOME/development/flutter/bin"
Install Xcode
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -runFirstLaunch
Install CocoaPods
sudo gem install cocoapods
Verify Installation
flutter doctor

eSellify supports three authentication methods. Enable each one in the Firebase Console.

1. Enable Phone Authentication

2. Enable Google Sign-In

3. Enable Apple Sign-In

Note:

Apple Sign-In requires an active Apple Developer account ($99/year). It is mandatory for iOS apps that offer third-party login options.

4. Add Authorized Domains (Required for Web)

For Phone Authentication to work on your web app, you must add your domain to the authorized domains list in Firebase.

Default domains: localhost and your-project-id.firebaseapp.com are added automatically. You only need to add your custom domain (e.g., yourdomain.com) if you are hosting the web app on your own domain.

eSellify uploads ad photos, profile pictures, verification documents and other media to Firebase Storage. You must enable Storage and update its security rules before these features will work.

1. Enable Storage in the Firebase Console

Note:

Enabling Cloud Storage requires the project to be on the Blaze (pay-as-you-go) plan if you are using a recently created Firebase project. A free Spark-plan bucket is sufficient for development and small deployments.

2. Update the Storage Security Rules

The following rules let ad images and profile pictures be viewed by everyone (including visitors who are not logged in, e.g. on the public web listings), while only signed-in users can upload files:

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if true;            // public read
      allow write: if request.auth != null;  // only signed-in users can upload
    }
  }
}
Important:

Never publish open rules such as allow read, write: if true; in production — this lets anyone upload or delete files in your bucket and can lead to abuse and unexpected billing.

The Customer Web build loads and uploads images (ad photos, profile pictures, verification documents) directly from your Firebase Storage bucket. Because the website and the storage bucket are on different domains, the browser blocks these requests unless the bucket has a CORS (Cross-Origin Resource Sharing) policy that allows your site. Configure CORS once per bucket.

When you need this:
  • Images don’t load on the customer web app and the browser console shows errors like "has been blocked by CORS policy" or "No 'Access-Control-Allow-Origin' header".
  • Uploading a photo from the web app fails while the same action works on the mobile app.

The mobile (Android/iOS) apps are not affected by CORS — this step is only required for the web build.

1. Install the Google Cloud SDK

gcloud auth login
gcloud config set project YOUR_PROJECT_ID

2. Create a cors.json File

[
  {
    "origin": [
      "https://your-domain.com",
      "https://your-project.web.app",
      "https://your-project.firebaseapp.com",
      "http://localhost:5000"
    ],
    "method": ["GET", "HEAD", "PUT", "POST", "DELETE"],
    "responseHeader": ["Content-Type", "Authorization", "Content-Length", "User-Agent", "x-goog-resumable"],
    "maxAgeSeconds": 3600
  }
]
Tip:

Keep http://localhost:5000 (and any other local port you use, e.g. http://localhost:8080) while developing, and add your live domain(s) before going to production. To allow any origin during testing you can use "origin": ["*"] — but restrict it to your real domains for production.

3. Apply the CORS Configuration

# Newer gcloud CLI
gcloud storage buckets update gs://YOUR_BUCKET_NAME --cors-file=cors.json

# Or the classic gsutil command
gsutil cors set cors.json gs://YOUR_BUCKET_NAME

4. Verify

gcloud storage buckets describe gs://YOUR_BUCKET_NAME --format="default(cors_config)"

# Or with gsutil
gsutil cors get gs://YOUR_BUCKET_NAME
Success:

Your Storage bucket now accepts cross-origin requests from your web app, so media loads and uploads work correctly in the browser.

Import the pre-built database collections to quickly populate your Firestore database with the required structure (categories, settings, currencies, subscription packages and more). This is a one-time step that gets a brand-new project ready to run.

Before you begin:
  • You have already created a Firebase project and connected it to the apps (see Setup Firebase).
  • You have the database.zip file that ships with the project package.
  • You have Owner or Editor access to the Firebase project.
  • Run these steps on a fresh, empty Firestore database. Importing over an existing database overwrites documents that share the same IDs.

1. Create the Firestore Database

A new Firebase project does not have a database yet — create it first, otherwise the import will fail.

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}
Important:

These open rules (allow read, write: if true;) make the database fully public and are intended for development and the initial data import only. Before launching, tighten them — for example, require authentication with allow read, write: if request.auth != null;.

2. Install Node.js and npm

node -v
npm -v

3. Extract Database Files

4. Open Terminal or Command Prompt

cd path/to/extracted/folder

5. Generate Firebase Service Account Key

The import script authenticates with a service-account key — this is different from the client config used inside the apps.

🔎 Navigation Path: Firebase Console → ⚙ (Gear Icon) → Project Settings → Service accounts tab → Firebase Admin SDK → Node.js → Generate new private key
Keep it secret:

The service-account key grants full admin access to your project. Never commit config.json to a public repository or share it publicly.

6. Install Dependencies

npm install firestore-export-import

7. Run the Import Command

node import

8. Verify in the Firebase Console

Success:

Once the import completes, your Firestore database will have all the required collections and documents. Next, deploy the indexes (see Firestore Database Indexing) so queries run efficiently.

Common errors:
  • "5 NOT_FOUND" / database does not exist — you skipped Step 1; create the Firestore database first.
  • "Could not load the default credentials" / config.json error — the service-account key is missing or not named exactly config.json (Step 5).
  • "command not found: node" — Node.js is not installed or the terminal wasn't restarted after installing it (Step 2).
  • "Cannot find module 'firestore-export-import'" — run the install command in Step 6 inside the correct folder.
Important Notes:
  • Ensure you are inside the correct project directory before running any Firebase CLI commands.
  • You must have sufficient permissions (e.g., Editor or Owner role) in your Firebase project to deploy indexes.
  • Once deployed, Firestore queries will benefit from better performance as they'll use the optimized indexes.

1. Navigate to Your Firebase Project Folder

cd path/to/firestore_index
Step A: Run firebase init
firebase init
Terminal Output:
You're about to initialize a Firebase project in this directory:
  C:\path\to\your\firestore_index

? Are you ready to proceed? (Y/n)
Step B: Select Firebase Features
Select this option:
(*) Firestore: Configure security rules and indexes files for Firestore

Use arrow keys to move, Space to select, Enter to confirm.

Step C: Choose Firebase Project
Step D: Set Up Firestore Rules and Indexes
Step E: Deploy Firestore Indexes
firebase deploy --only firestore:indexes
Deployment Complete
Expected Terminal Output:
=== Deploying to 'your-project-id'...

i  firestore: reading indexes from firestore.indexes.json...
i  cloud.firestore: checking firestore.rules for compilation errors...
+  cloud.firestore: rules file firestore.rules compiled successfully
i  firestore: deploying indexes...
+  firestore: deployed indexes in firestore.indexes.json successfully

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/your-project-id/overview

eSellify uses Firebase Cloud Functions to send transactional emails. Follow these steps to deploy them on a fresh Firebase project.

Step 1: Prerequisites

npm install -g firebase-tools
Blaze Plan Required: Cloud Functions require the Blaze (Pay as you go) plan. Upgrade in Firebase Console > your project > Upgrade. The Blaze plan still includes generous free tiers.

Step 2: Set Your Firebase Project ID

Open function/.firebaserc and replace the project ID with yours:

{
  "projects": {
    "default": "your-firebase-project-id"
  }
}
Find your Project ID: Firebase Console > Project Settings (gear icon) > General tab.

Step 3: Install Dependencies

Open a terminal in the project root and run:

cd function/functions
npm install
Node version must match: The "node": "22" in functions/package.json must match your local Node.js version. If you have Node 20, change it to "20".

Step 4: Deploy

Navigate back to the function directory and deploy:

cd ..
firebase deploy --only functions

Expected output on success:

i  functions: preparing codebase default for deployment
+  functions: functions source uploaded successfully
i  functions: creating Node.js 22 (2nd Gen) function sendSmtpTestEmail(us-central1)...
i  functions: creating Node.js 22 (2nd Gen) function sendTransactionalEmail(us-central1)...
+  functions[sendSmtpTestEmail(us-central1)] Successful create operation.
+  functions[sendTransactionalEmail(us-central1)] Successful create operation.

+  Deploy complete!
First deployment may take 2–5 minutes as Firebase builds the container image. Subsequent deployments are faster.

Step 5: Verify Deployment

Confirm both functions are live:

firebase functions:list

You should see:

+------------------------+---------+----------+-------------+--------+----------+
| Function               | Version | Trigger  | Location    | Memory | Runtime  |
+------------------------+---------+----------+-------------+--------+----------+
| sendSmtpTestEmail      | v2      | callable | us-central1 | 256    | nodejs22 |
+------------------------+---------+----------+-------------+--------+----------+
| sendTransactionalEmail | v2      | callable | us-central1 | 256    | nodejs22 |
+------------------------+---------+----------+-------------+--------+----------+

Deploying a Single Function (Optional)

To redeploy only one function after making changes:

firebase deploy --only functions:sendTransactionalEmail

Checking Logs

If something isn't working, check the function logs:

firebase functions:log --only sendTransactionalEmail

You can also view logs in the Firebase Console > Functions > Logs tab.

Here you will find all the setup guides for Admin Panel configuration.

Important Notes:
  • Some Firebase features require the Blaze plan.
  • If you are on the free Spark plan, please upgrade to Blaze Plan for full functionality.

Update HTML Title

<head>
  ...
  <title>Your New App Name</title>
  ...
</head>

1. Install Firebase CLI Tools

npm install -g firebase-tools

2. Authenticate Firebase CLI

firebase login

3. Create a Firebase Project

firebase projects:create

OR

1 Add Firebase to your Flutter App:
  • On the Firebase Project Overview page, you will see the text "Get started by adding Firebase to your app" with platform icons (iOS, Android, Web, Unity, Flutter).
  • Click the Flutter icon (the last icon, looks like a diamond shape).
  • Firebase will show the "Add Firebase to your Flutter app" wizard with two commands.
2 Run the FlutterFire CLI commands shown in the wizard:
$ dart pub global activate flutterfire_cli
$ flutterfire configure --project=YOUR_PROJECT_ID

This automatically registers your per-platform apps with Firebase and adds a lib/firebase_options.dart configuration file to your Flutter project.

  • After running both commands, click Next in the Firebase wizard.
  • Then click Continue to console.

4. Initialize Firebase in Your Flutter App

dart pub global activate flutterfire_cli
flutterfire configure --project=YOUR_PROJECT_ID
Platform Selection (Admin Panel = Web only):
? Which platforms should your configuration support?
  ( ) android
  ( ) ios
  ( ) macos
  (*) web        <-- Select ONLY this
  ( ) windows

Use arrow keys and Space to select web only. Press Enter to confirm.

1. Generate a Google Maps API Key

2. Add API Key to Flutter Web

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>

Flutter Web

For Flutter web, the favicon represents your application in the browser tab.

Replace Favicon:
Tip:

You can use online tools like favicon.io or realfavicongenerator.net to generate favicons from your logo in all required sizes.

Important:

Do not upload the source code to your server — it will not work. Complete the Firebase setup first, then run flutter build web --release and upload only the generated build/web/ folder.

Note:

Run all commands below from the project folder in your Android Studio terminal or system terminal.

1. Create the Build for Server Upload

flutter clean
flutter pub get
flutter build web --release
Compiling lib/main.dart for the Web...
✓ Built build\web                                          19.5s
build/web/
Note:

Run all commands below from the project folder in your terminal.

1. Build and Deploy Using Firebase Hosting

npm install -g firebase-tools
firebase login
firebase init
Follow the Firebase Init prompts:
? Are you ready to proceed? (Y/n) y

? Which Firebase features do you want to set up?
  (*) Hosting: Configure files for Firebase Hosting
      and (optionally) set up GitHub Action deploys

=== Project Setup
? Please select an option: Use an existing project
i  Using project your-project-id

=== Hosting Setup
? What do you want to use as your public directory? build/web
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? Set up automatic builds and deploys with GitHub? No
flutter build web --release
firebase deploy
Expected Deployment Output:
=== Deploying to 'esellify-app'...

i  deploying firestore, hosting
i  hosting[esellify-app]: beginning deploy...
i  hosting[esellify-app]: found 516 files in build/web
+  hosting[esellify-app]: file upload complete
+  hosting[esellify-app]: version finalized
+  hosting[esellify-app]: release complete

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/esellify-app/overview
Hosting URL: https://esellify-app.web.app
Success:

Your Admin Panel is now live! Copy the Hosting URL shown in the output (e.g., https://esellify-app.web.app) to access your deployed admin panel.

The customer_web module is the responsive Flutter web build of the customer application — same Firebase backend as the mobile app, same business logic, but redesigned for desktop/tablet browsers with a header + footer shell. Follow the steps below to configure and deploy it.

Important Notes:
  • The customer web uses the same Firebase project as your admin panel and mobile apps.
  • Some features (App Check, flutter_local_notifications) are mobile-only and are auto-skipped on web via kIsWeb guards already in the code.

1. Update HTML Title & Meta

<title>Your New App Name</title>
<meta name="description" content="Your short app description">
<meta name="apple-mobile-web-app-title" content="Your App Name">

2. Update PWA Manifest

{
  "name": "Your App Name",
  "short_name": "AppShort",
  "description": "Your app description",
  "theme_color": "#3068FF",
  ...
}

Customer Web needs Firebase credentials in three places. All three must use the same web app from your Firebase project.

1. Get Your Firebase Web Config

2. Update web/index.html

window.firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT.firebasestorage.app",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID",
  measurementId: "YOUR_MEASUREMENT_ID"
};

3. Update web/firebase-messaging-sw.js

4. Update lib/firebase_options.dart

static const FirebaseOptions web = FirebaseOptions(
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  messagingSenderId: 'YOUR_SENDER_ID',
  projectId: 'YOUR_PROJECT_ID',
  authDomain: 'YOUR_PROJECT.firebaseapp.com',
  storageBucket: 'YOUR_PROJECT.firebasestorage.app',
  measurementId: 'YOUR_MEASUREMENT_ID',
);
⚠️ All three must match

Flutter reads from firebase_options.dart, while the JS SDK in index.html and the background service worker firebase-messaging-sw.js read their own copies. If the three are not identical you will get authentication errors or silent FCM failures.

Customer Web uses Google Maps for the location picker, address selection, and ad-detail map embed. If you already created a Google Maps API key for your admin panel or mobile app, you can reuse it — just make sure the key has the Maps JavaScript API and Places API enabled and is not restricted to a different referrer.

1. Enable Required APIs

2. Add Your API Key to web/index.html

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>

3. Restrict the Key (Recommended)

Note:

Run all commands from the customer_web/ folder.

1. Install Dependencies

flutter clean
flutter pub get

2. Launch in Chrome

flutter run -d chrome

3. Optional: Custom Port

flutter run -d chrome --web-port 5000
Important:

Do not upload the source code to your server — it will not work. Configure Firebase first, then build with flutter build web --release and upload only the generated customer_web/build/web/ folder.

Note:

Run all commands from the customer_web/ folder.

1. Build the Release Bundle

flutter clean
flutter pub get
flutter build web --release
customer_web/build/web/

2. Deploy Option A: Any Web Server (FTP / cPanel / Nginx)

Apache .htaccess example:
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
Nginx example:
location / {
  try_files $uri $uri/ /index.html;
}

3. Deploy Option B: Firebase Hosting

npm install -g firebase-tools
firebase login
firebase init hosting
Follow the prompts:
? Please select an option: Use an existing project
? Select a default Firebase project: your-project-id

? What do you want to use as your public directory? build/web
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? Set up automatic builds and deploys with GitHub? No
? File build/web/index.html already exists. Overwrite? No
⚠️ Answer "No" to overwriting index.html

Always answer No when asked to overwrite existing build/web/index.html — otherwise Firebase will replace your custom index.html (with the Firebase JS SDK + reCAPTCHA container) with a blank template and the app will fail to initialize.

flutter build web --release
firebase deploy --only hosting
Success:

Your Customer Web is now live. The deploy command will print a Hosting URL (e.g. https://your-project.web.app) — that's your production URL.

4. Post-Deploy Checklist

Here you will find all the setup guides for configuring the Customer & Seller Apps (Android & iOS).

Changing the package name of a Flutter project involves updating multiple files and configurations for both Android and iOS platforms.

Android

Update the applicationId in build.gradle:
defaultConfig {
    applicationId "com.new.package.name"
}
Rename Java Package Directories:
Update AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.new.package.name">
</manifest>
Update Other Manifest Files:

iOS

Update PRODUCT_BUNDLE_IDENTIFIER in Xcode:
Update Bundle Identifier in Info.plist:

Prerequisites

Android

Update AndroidManifest.xml:
<application
    android:name="${applicationName}"
    android:icon="@mipmap/ic_launcher"
    android:label="Your App Name"
    ...>
</application>
Update strings.xml:
<string name="app_name">Your New App Name</string>

iOS

Update Info.plist:
<key>CFBundleName</key>
<string>Your New App Name</string>
Update Display Name in Xcode:
Note:

This setup applies to both the Admin Panel, Customer App, and Seller App. The steps are identical.

1. Install Firebase CLI Tools

npm install -g firebase-tools

2. Authenticate Firebase CLI

firebase login

3. Create a Firebase Project

firebase projects:create

OR

On the Project Overview page, click the Flutter icon under "Get started by adding Firebase to your app". The wizard will show two commands to run:
$ dart pub global activate flutterfire_cli
$ flutterfire configure --project=YOUR_PROJECT_ID

Run both in your project terminal. Then click NextContinue to console.

4. Initialize Firebase in Your Flutter App

dart pub global activate flutterfire_cli
flutterfire configure --project=YOUR_PROJECT_ID
Platform Selection (Customer/Seller App = Android & iOS):
? Which platforms should your configuration support?
  (*) android    <-- Select this
  (*) ios        <-- Select this
  ( ) macos
  ( ) web
  ( ) windows

Use arrow keys and Space to select android and ios. Press Enter.

Firebase configuration file lib/firebase_options.dart generated successfully
with the following Firebase apps:

Platform  Firebase App Id
android   1:XXXXXXXXX:android:XXXXXXXXX
ios       1:XXXXXXXXX:ios:XXXXXXXXX

1. Create a Firebase Project

2. Add Your Flutter App to Firebase

Android Setup:
iOS Setup:

3. Add Firebase Packages

dependencies:
  firebase_core: ^latest
  firebase_auth: ^latest
  cloud_firestore: ^latest
flutter pub get

4. Configure DefaultFirebaseOptions

flutterfire configure

5. Initialize Firebase in main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(MyApp());
}

1. Generate a Google Maps API Key

2. Add API Key - Android

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_API_KEY"/>

3. Add API Key - iOS

import GoogleMaps
GMSServices.provideAPIKey("YOUR_API_KEY")
Security Tip:
  • Restrict your API key in the Google Cloud Console to specific apps (using package name/bundle ID) and specific APIs to prevent unauthorized usage.

SHA keys are required for Firebase services like Google Sign-In and Phone Authentication on Android.

1. Generate SHA Keys

For Windows (Debug Keystore):
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
For macOS/Linux (Debug Keystore):
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

2. Add SHA Keys to Firebase Console

🔎 Navigation Path: Firebase Console → ⚙ Gear Icon → Project Settings → General tab → Your apps → Android app → Add Fingerprint
Important Notes:
  • For release builds, use your custom release keystore (not the default debug one).
  • Keep your keystore file secure and never expose it publicly.
  • You must regenerate SHA keys if you change your signing configuration or keystore.

Before generating a release APK or AAB, you must set up a release keystore and configure your Gradle build to use it. This is required for publishing to the Google Play Store.

1. Generate a Release Keystore

Run the following command in your terminal to create a new keystore file. Replace the placeholder values with your own information:

For Windows:
keytool -genkey -v -keystore %USERPROFILE%\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload
For macOS / Linux:
keytool -genkey -v -keystore ~/upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload

2. Create key.properties

Create a file named key.properties inside the android/ folder of your Flutter project. Paste the following contents and replace the placeholder values:

storePassword=YOUR_KEYSTORE_PASSWORD
keyPassword=YOUR_KEY_PASSWORD
keyAlias=upload
storeFile=/path/to/your/upload-keystore.jks
⚠️ Security Warning

Never commit key.properties or your .jks keystore file to Git. Add both to your .gitignore:

android/key.properties
*.jks

3. Configure Gradle for Release Signing

Open android/app/build.gradle and add the following changes:

Step A: Load the key.properties file (add above the android { block):
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
Step B: Add the signingConfigs block (inside the android { block, before buildTypes):
signingConfigs {
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
        storePassword keystoreProperties['storePassword']
    }
}
Step C: Update buildTypes to use the release signing config:
buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}

4. Generate Release SHA Keys

After creating your release keystore, generate the SHA-1 and SHA-256 keys for the release keystore and add them to Firebase (same process as the debug keys above):

keytool -list -v -keystore /path/to/upload-keystore.jks -alias upload
🔎 Quick Reference:
  1. keytool -genkey ... → creates upload-keystore.jks
  2. Create android/key.properties with passwords + path
  3. Load in build.gradle → add signingConfigs.release → reference in buildTypes.release
  4. Generate release SHA keys → add to Firebase Console
Note:

Run all commands from your project folder in the terminal.

1. Generate APK (for direct installation)

flutter clean
flutter pub get
flutter build apk --release
build/app/outputs/flutter-apk/app-release.apk

2. Generate AAB (for Google Play Store)

flutter clean
flutter pub get
flutter build appbundle --release
build/app/outputs/bundle/release/app-release.aab
Difference between APK and AAB:
  • APK: Universal package for direct installation or testing on devices.
  • AAB: Optimized format required by Google Play Store. It generates smaller, device-specific APKs automatically.

Using Command-Line Interface (CLI)

Open Terminal and navigate to your project:
cd path/to/your_flutter_project
Run the Flutter App:
flutter run

Using Android Studio

Using Visual Studio Code

Useful Flutter Commands:
  • flutter devices - List all connected devices
  • flutter run -d chrome - Run on Chrome (web)
  • flutter run -d <device_id> - Run on a specific device
  • flutter run --release - Run in release mode

1. Get Notification Sender ID

🔎 Navigation Path: ⚙ Gear Icon → Project Settings → Cloud Messaging tab → Sender ID

2. Get Web Push Certificate (VAPID Key)

🔎 Navigation Path: Project Settings → Cloud Messaging tab → Web configuration → Web Push certificates → Copy Key pair

3. Get Web Client ID (for Google Sign-In)

🔎 Navigation Path: Authentication → Sign-in method → Google (edit) → Web SDK configuration → Web client ID

4. Get Firebase Service Account JSON File

🔎 Navigation Path: ⚙ Gear Icon → Project Settings → Service accounts tab → Generate new private key

5. Add All Keys in Admin Panel

Admin Panel → Settings → Notification Settings:
Field What to Enter
Notification Sender Key The Sender ID copied from Cloud Messaging tab
Web Notification Key The VAPID Key copied from Web Push certificates
Client ID for Google Login The Web client ID from Authentication → Google
Upload JSON File The Service Account JSON file downloaded from Firebase

1. Add Notification Key in Admin Panel

2. Configure Firebase Messaging in Flutter Web

How to get Firebase config values:
Update firebase-messaging-sw.js:
// Give the service worker access to Firebase Messaging.
importScripts('https://www.gstatic.com/firebasejs/10.7.1/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.7.1/firebase-messaging-compat.js');

// Your Firebase Config
firebase.initializeApp({
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
  measurementId: "YOUR_MEASUREMENT_ID"
});

const messaging = firebase.messaging();
💡 One config, all pages

Firebase credentials for the Landing Page are now stored in one shared file: landing-page/firebase-config.js. This single file is automatically used by index.html, privacy-policy.html, and terms-and-conditions.html — so you only need to update your credentials in one place.

1. Open the Shared Firebase Config File

// landing-page/firebase-config.js
var firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
  measurementId: "YOUR_MEASUREMENT_ID"
};

2. Get Firebase Credentials

No Web App shown?

If no Web App is listed, click "Add app" → select the Web icon (</>) → enter a nickname → click "Register app". The firebaseConfig will then appear.

3. Replace the Config

⚠️ Do not add firebase.initializeApp() to individual HTML files

The shared firebase-config.js already calls firebase.initializeApp() and exposes window.db for every page. Duplicating the init call inside index.html or any other HTML file will cause a "Firebase App named '[DEFAULT]' already exists" error.

🔎 Navigation Path: Firebase Console → ⚙ Gear Icon → Project Settings → General tab → Your apps → Web app → SDK setup and configuration → Copy firebaseConfig → Paste into landing-page/firebase-config.js

This section applies to Admin Panel and Customer Web when hosted on Hostinger, cPanel, or any shared Apache / LiteSpeed hosting. It fixes the three most common problems: changes not reflecting after re-upload, direct URLs returning 404, and blank white pages.

Upload the build, not the source:

You can only upload a compiled build to shared hosting. Set up Firebase, run flutter build web --release, and upload the contents of the build/web/ folder — uploading the project source code will not work.

⚠️ Why changes don't reflect after upload
  • Flutter's service worker (flutter_service_worker.js) aggressively caches the old build. Visitors keep seeing the old version until the cache is busted.
  • Hostinger's LiteSpeed cache caches index.html at the server level.
  • Browser caching of main.dart.js and other assets.

1. Add an .htaccess file to your web folder

Create a file named .htaccess inside your project's web/ folder (so Flutter copies it into build/web/ on every build) with the following contents:

# ── SPA route rewrite ─────────────────────────────────
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
</IfModule>

# ── Never cache index.html and service worker ─────────
<IfModule mod_headers.c>
    <FilesMatch "^(index\.html|flutter_service_worker\.js|flutter_bootstrap\.js|manifest\.json)$">
        Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
        Header set Pragma "no-cache"
        Header set Expires "0"
    </FilesMatch>

    # Long cache for hashed static assets
    <FilesMatch "\.(js|wasm|woff2?|ttf|otf|png|jpg|jpeg|gif|svg|ico)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
</IfModule>

# ── Gzip compression ──────────────────────────────────
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml font/ttf font/otf application/wasm
</IfModule>

# ── Correct MIME types (fixes blank page) ─────────────
<IfModule mod_mime.c>
    AddType application/wasm .wasm
    AddType application/javascript .js
    AddType application/manifest+json .webmanifest
</IfModule>

# ── Disable LiteSpeed cache for entry files ───────────
<IfModule LiteSpeed>
    <FilesMatch "^(index\.html|flutter_service_worker\.js|flutter_bootstrap\.js|manifest\.json)$">
        CacheDisable public
    </FilesMatch>
</IfModule>

ErrorDocument 404 /index.html

This project already ships with this file at admin_panel/web/.htaccess and customer_web/web/.htaccess — any build will carry it into build/web/ automatically.

2. Build the release bundle

flutter clean
flutter pub get
flutter build web --release

3. Upload to Hostinger

💡 Make hidden files visible in Hostinger File Manager

By default the File Manager hides dotfiles. Click the gear icon (settings) in the top-right of File Manager and enable "Show hidden files" so you can see and upload .htaccess.

4. Purge Hostinger's LiteSpeed cache

5. Force-refresh your browser

Even with the new .htaccess, any visitor who already loaded the old service worker still has it installed. The first visit after your upload may still show the old version. To verify immediately:

6. Verify the deploy

Common Hostinger-specific issues

Blank white page after upload
Direct URLs (e.g. /ad-listing-detail) return 404
Old version keeps loading

eSellify ships with three optional features that are configured entirely from the Admin Panel — no code changes required. Each is described below.

When enabled, sellers can auto-fill an ad from its photos. The app sends the uploaded images (plus an optional product-name hint) to OpenAI Vision, which generates the title, description, suggested price, best-fit category and any custom-field values for that category.

1. Get an OpenAI API Key

2. Configure in the Admin Panel

3. How Sellers Use It

Security note:

The OpenAI key is stored in your Firestore settings and read by the apps. Keep the feature disabled if you don’t intend to use it, and monitor usage in your OpenAI dashboard. The key field is masked in the admin UI when running in demo mode.

Safety Tips are short buyer-safety reminders shown in a bottom sheet when a user taps Chat or Make an offer on a listing (similar to OLX). The list is fully managed from the admin panel — no app update needed.

Manage the Tips

Note:

If no active tips are configured, the safety bottom sheet is skipped automatically and the buyer goes straight to chat / offer, so the feature never blocks the contact flow.

Here are solutions to common issues you might encounter during setup.

Flutter Issues

"flutter" is not recognized as a command
flutter doctor shows issues

Firebase Issues

Firebase CLI not found
Permission denied during firebase deploy

Cloud Functions Issues

Error: "Your project must be on the Blaze (pay-as-you-go) plan"
Error: "Cannot set CPU on gen 1 functions"
Deployment fails with API errors
Node version mismatch error

Google Maps Issues

Map shows grey/blank

Build Issues

Build fails with Gradle errors
iOS build fails
Q: Do I need a Mac to build the iOS app?

Yes. Xcode is required for building iOS apps, and Xcode only runs on macOS. You can develop and test the Android and Web versions on Windows or Linux.

Q: Which Firebase plan do I need?

The Blaze plan (pay-as-you-go) is recommended. phone authentication, and some other features are not available on the free Spark plan. The Blaze plan still includes a free usage tier.

Q: Can I use my own backend instead of Firebase?

eSellify is designed to work with Firebase. Using a different backend would require significant modifications to the codebase.

Q: How do I update the app after making changes?

After making code changes, rebuild the app using the appropriate build commands (flutter build apk, flutter build web, etc.) and redeploy.

Q: The app crashes on startup. What should I check?
Q: Which payment gateways are supported?

eSellify supports Stripe, Razorpay, PayPal, Flutterwave, and Cash on Delivery (COD). You can configure your preferred gateway in the Admin Panel settings.

Q: How do I contact support?
Version 1.3 23 May 2026 Latest
  • Send Test Email — added functionality for SMTP/email configuration testing.
  • Ad Details screen — created a dedicated Ad Details screen in the Admin Panel.
  • Job Category flow — implemented the complete Job Category flow, including job applications visibility in the customer app.
  • Job Applications in Admin — added functionality to view users' job applications in the Admin Panel.
  • Dependency upgrades — upgraded project dependencies/packages to the latest compatible versions.
  • Bug fixes & stability — fixed minor bugs and improved overall app performance and stability.
Version 1.2 12 May 2026
  • Google AdMob & AdX integration — banner, interstitial and native ads on mobile, GPT banner on web, configured from a new admin panel.
  • Safety Tips feature — admin-managed buyer-safety reminders shown in a bottom sheet before contacting a seller.
  • AI-generated ad content — OpenAI Vision auto-fills title, description, price, category and custom fields from uploaded product photos.
Version 1.1 18 April 2026
  • Completed full conversion of the mobile application into a high-performance web version.
  • Introduced web-based paginated ad listings with precise distance-based filtering.
  • Upgraded to Flutter 3.41.6 for improved compatibility.
  • Updated all project dependencies to their latest stable versions.
  • Refined the web platform with critical bug fixes and enhanced navigation performance.
  • Optimized the web experience with proximity-sorted ads and smooth paginated browsing.
Version 1.0 11 April 2026
  • Initial Release.