HandyHive Documentation

Setup and deployment guide for your multi-platform home-services app.

v8.4 - 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.

🗺

Location & Zones

Google Maps with admin-defined service zones, polygon area drawing, and Places autocomplete.

🔔

Push Notifications

Real-time FCM notifications for booking, status, and chat events on all platforms.

Admin Panel

Full-featured Flutter web dashboard for managing bookings, users, providers, workers, services, payouts, subscriptions, and the public landing page.

💰

Subscriptions & Payouts

Provider subscription plans with automated billing, plus a payout request workflow with admin approval and history.

🌐

Public Landing Page

Standalone HTML/CSS/JS marketing site; all content (hero, features, testimonials, FAQ, app links) is editable from the admin panel.

Serverless Backend

Firebase Cloud Functions, Firestore, and Storage — scalable and serverless, with no servers to maintain.

What's Included

Everything you need to launch your home-services platform:

Make sure you have these tools and accounts ready before you start.

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
Node.js & npm LTS version Firebase CLI & Cloud Functions
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 (Cloud Functions, 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. Each one links to its detailed section below.

Estimated Setup Time

The full setup usually takes 1-2 hours, depending on your Flutter and Firebase experience.

Follow these steps to set up Flutter on Windows or macOS.

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

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

📱

1. Phone Authentication

  • Open the Firebase Console and select your project.
  • In the sidebar, click "Authentication".
  • Open the "Sign-in method" tab.
  • Find "Phone", click the edit icon, toggle it on, and click Save.
👤

2. Google Sign-In

  • In the same Sign-in method tab, click the edit icon next to "Google".
  • Toggle Enable on.
  • If asked, fill in the OAuth consent screen:
    • App name
    • Support email
    • Developer contact details
  • Save.

3. Apple Sign-In

  • In Authentication > Sign-in method, click the edit icon next to Apple.
  • Enable it and add your Apple Developer credentials:
    • Team ID
    • Service ID
    • Key ID
    • Private Key (.p8 file)
  • Save.
Note:

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

Import the pre-built collections to set up your Firestore database structure quickly.

1. Install Node.js and npm

node -v
npm -v

2. Extract Database Files

3. Open Terminal or Command Prompt

cd path/to/extracted/folder

4. Generate Firebase Service Account Key

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

5. Prepare config.json

6. Run Import Command

npm install firestore-export-import
node import
Success:

Once the import completes, your Firestore database will have all the required collections and documents.

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, your Firestore queries run faster using 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

1. Install Firebase CLI Tools

npm install -g firebase-tools
firebase --version

2. Firebase Project Setup

Log in to Firebase:
firebase login
Important:
  • Run all commands below from your Cloud Functions project directory (e.g., your-project/functions/).
Initialize Firebase (if not already initialized):
firebase init
During this process, follow these prompts:
Firebase Init Prompts for Cloud Functions:
? Are you ready to proceed? Yes
? Which Firebase features do you want to set up?
  (*) Functions: Configure a Cloud Functions directory and its files

=== Project Setup
? Please select an option: Use an existing project
? Select a default Firebase project: your-project-id

=== Functions Setup
? What language would you like to use? JavaScript
? Do you want to use ESLint? No
? Do you want to install dependencies with npm now? Yes
+  Wrote functions/package.json
+  Wrote functions/index.js
+  Wrote functions/.gitignore
+  Wrote configuration info to firebase.json
+  Wrote project information to .firebaserc

+  Firebase initialization complete!

3. Install Function Dependencies

cd functions
npm install

4. Deploy Your Functions

firebase deploy --only functions
Expected Terminal Output:
=== Deploying to 'your-project-id'...

i  deploying functions
i  functions: preparing codebase default for deployment...
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
+  functions: required API cloudfunctions.googleapis.com is enabled
i  functions: Loading and analyzing source code...

+  Deploy complete!

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

If deployment fails, check your function files for syntax errors, confirm all dependencies are installed, and verify you're on the Blaze plan.

Setup guides for configuring the Admin Panel.

Important Notes:
  • Some Firebase features require the Blaze plan.
  • On the free Spark plan, upgrade to Blaze 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, find "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 opens 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 registers your per-platform apps with Firebase and adds a lib/firebase_options.dart file to your 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

On Flutter web, the favicon represents your app in the browser tab.

Replace Favicon:
Tip:

Use tools like favicon.io or realfavicongenerator.net to generate favicons from your logo in all sizes.

Configure CORS (Cross-Origin Resource Sharing) on your Firebase Storage bucket so the web panel can load images and files.

1. Open the Google Cloud Console

2. Select Your Project

3. Activate Google Cloud Shell

Welcome to Cloud Shell! Type "help" to get started.
Your Cloud Platform project in this session is set to your-project-id.
Use 'gcloud config set project [PROJECT_ID]' to change to a different project.

4. Create a CORS Configuration File

echo '[{ "origin": ["*"], "method": ["GET"], "maxAgeSeconds": 3600, "responseHeader": ["Content-Type"] }]' > cors-config.json

5. Get Your Storage Bucket Name

6. Apply the CORS Configuration to Your Bucket

gsutil cors set cors-config.json gs://YOUR_BUCKET_NAME
Security Note:
  • The "origin": ["*"] setting allows requests from any domain. For production, restrict it to your own domain for better security.
Note:

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

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 'handyhive-3d7fa'...

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

+  Deploy complete!

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

Your Admin Panel is live! Open the Hosting URL from the output (e.g., https://handyhive-3d7fa.web.app) to access it.

These steps apply to all three Flutter mobile apps — Customer (handyhive_customer/), Partner (handyhive_partner/), and Worker (handyhive_worker/) — on both Android and iOS.

Changing the package name means updating several files on both Android and iOS.

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 all four Flutter projects — the Admin Panel (web) and the three mobile apps (Customer, Partner, Worker). The steps are identical — just run them once inside each project folder, picking the appropriate platforms in step 4.

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 — pick per project:
? Which platforms should your configuration support?
  (*) android      <-- Customer / Partner / Worker apps
  (*) ios          <-- Customer / Partner / Worker apps
  ( ) macos
  (*) web          <-- Admin Panel only
  ( ) windows

Mobile apps (handyhive_customer, handyhive_partner, handyhive_worker): select android + ios.
Admin panel (admin_panel): select web only.

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:
  • In the Google Cloud Console, restrict your API key to specific apps (by package name/bundle ID) and APIs to prevent misuse.

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.
  • Regenerate SHA keys whenever you change your signing config or keystore.

A JKS (Java KeyStore) file holds the private key used to digitally sign your Android release builds. Google Play requires every APK/AAB to be signed, and all future updates must use the same key — so create this keystore once and keep it safe.

Note:

You need the keytool command, which ships with the JDK (already installed with Android Studio / Flutter). Run all commands from your terminal.

1. Generate the Keystore with keytool

Run the command below in your terminal to generate the JKS file used for Android app signing only. Replace (Project_name) with your own project name — the file is created in the current folder.

keytool -genkey -v -keystore (Project_name).jks -keyalg RSA -keysize 2048 -validity 10000 -alias (Project_name)

2. Answer the Prompts

Example prompts:
Enter keystore password:  ********
Re-enter new password:    ********
What is your first and last name?
  [Unknown]:  Your Name
What is the name of your organizational unit?
  [Unknown]:  HandyHive
...
Is CN=Your Name, OU=HandyHive, ... correct?
  [no]:  yes

Enter key password for <(Project_name)>
        (RETURN if same as keystore password):

3. Move the Keystore into Your Project

Important:
  • Add the keystore and its passwords to .gitignorenever commit them to version control.

4. Create a key.properties File

# android/key.properties
storePassword=YOUR_KEYSTORE_PASSWORD
keyPassword=YOUR_KEY_PASSWORD
keyAlias=(Project_name)
storeFile=(Project_name).jks

5. Reference the Keystore in build.gradle

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

6. Build the Signed Release

flutter build apk --release
# or
flutter build appbundle --release
Important Notes:
  • Back up your JKS file and passwords in a secure place. If you lose them, you cannot publish updates to your existing app on Google Play.
  • Use the same keystore for every release of the same app — a new key creates a different app identity.
  • Keep the keystore and key.properties out of Git and away from public sharing.
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. It auto-generates smaller, device-specific APKs.

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 the FCM Sender ID

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

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

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

3. Get the Firebase Service Account JSON File

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

4. Add All Keys in the Admin Panel

Admin Panel → Settings → Notification Settings:
Field What to Enter Stored in Firestore as
FCM Server Key The Sender ID from Cloud Messaging tab (Step 1) notification_server_key
Google Client ID The Web client ID from Authentication → Google (Step 2) googleClientId
Service Account JSON Upload the JSON file generated in Step 3 jsonFileURL
Note — where each setting lives in the Admin Panel:

Settings → Notification Settings: FCM Server Key, Service Account JSON, Google Client ID (this page).
Settings → General Settings: Google Maps key, Support URL, App version — configured separately.

HandyHive includes a standalone marketing site in the landing_page/ folder (next to admin_panel/). All text and images are editable from the admin panel under Content → Landing Page and render from Firestore at runtime — no redeploy needed when content changes.

Folder Structure

HandyHive/
  admin_panel/                 Flutter web admin (the "Landing Page" editor lives here)
  landing_page/                Plain HTML/CSS/JS marketing site (this section)
    index.html                 Markup skeleton with data-bind attributes
    styles.css                 Theme tokens (purple #AD5CFF) + responsive layout
    config.js                  Firebase Web config (edit this for your project)
    app.js                     Listens to settings/landing_page and renders the page
    README.md                  Quick start notes

1. Update Firebase Credentials

// landing_page/config.js
window.HH_FIREBASE_CONFIG = {
  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. Firestore Security Rule

The landing page reads settings/landing_page without authentication, so that document needs to be publicly readable. Add this rule to your firestore.rules (write access stays admin-only):

match /databases/{database}/documents {
  match /settings/landing_page {
    allow read: if true;                       // public can read
    allow write: if request.auth != null;      // only authenticated admins write
  }
}

4. Edit Content from Admin Panel

Sign in to the admin panel and navigate to Content → Landing Page. The editor is split into nine sections:

Click Save. The landing page subscribes to Firestore via onSnapshot, so any open tab updates live — visitors don't even need to reload.

5. Image Uploads

The Logo, Favicon, Hero background, App preview, and Testimonial avatars are real image pickers. Picking a file uploads it to Firebase Storage and saves the download URL on the Firestore document. Files go to these folders:

Make sure your storage.rules allows authenticated admins to write to these paths.

6. Running Locally

The landing_page/ folder is a plain static site — no build step.

  1. Double-click index.html — the browser opens via file://. The page renders with its built-in default copy if the browser blocks file:// network requests.
  2. Serve it over HTTP (recommended — required for Firebase to load):
    cd landing_page
    python3 -m http.server 8080
    # or
    npx serve .
    Then open http://localhost:8080/.

Open DevTools → Console. Any errors from the Firestore listener appear tagged [LandingPage] — use them to debug missing fields or permission denied errors.

7. Deploying to Production

Deploy the folder to any static host:

Option A — Firebase Hosting (recommended)
npm install -g firebase-tools
cd landing_page
firebase login
firebase init hosting
# - Use an existing project → your HandyHive Firebase project
# - Public directory: .  (this current folder)
# - Configure as SPA? → No
# - Set up automatic builds? → No
# - Overwrite index.html? → No

firebase deploy --only hosting

You'll receive a live URL like https://your-project.web.app.

Option B — Any other static host

Upload the whole landing_page/ folder to Netlify, Vercel, GitHub Pages, AWS S3 + CloudFront, or your own server. No build step required.

8. Troubleshooting

Page shows the default copy instead of my admin-panel content
Image uploads show "Upload failed"
Logo or favicon doesn't update on the live site
Play Store / App Store buttons go nowhere
Setup Complete: edit landing_page/config.js → save content from Content → Landing Page → deploy. Your landing page is live and fully admin-driven.

HandyHive's multi-language support spans the whole system. The Admin Panel is where you register and manage the available languages, and all three mobile apps (Customer, Partner, Worker) show their UI in the language each user picks. Localization uses GetX and has three roles you must keep in sync:

Important — how the parts relate:

Adding a language in the Admin Panel only adds the option to the language list. The strings do not download from Firestore. If you add a language code (e.g. pt) in the panel but there is no matching app_pt.dart strings file registered in the app, selecting that language will show the raw English keys (untranslated). Both steps are required.

1. Add a Language in the Admin Panel

Admin Panel → Global Settings → Languages → Add language:
Field What to Enter Example
Language name Display name shown in the app's language list English / हिंदी / العربية
Code The ISO language code — must exactly match the key used in the app's strings file and translation map en / hi / ar
// Firestore: languages/{autoId}
{
  "id":     "Xy12Ab34Cd56Ef78Gh90",
  "name":   "Hindi",
  "code":   "hi",
  "active": true
}
🔎 Navigation Path: Admin Panel → Global Settings → Languages → Add language → enter Name + Code → Save

2. App-Side Files You Need

Every app keeps its translations under lib/lang/ and registers them in one LocalizationService. The structure is identical across all three apps:

handyhive_customer/   (also handyhive_partner/ and handyhive_worker/)
  lib/
    lang/
      app_en.dart                  English strings   -> const Map enUS
      app_hi.dart                  Hindi strings     -> const Map hiIN
      app_ar.dart                  Arabic strings    -> const Map lnAr
    services/
      localization_service.dart    Registers the maps with GetX

3. How Strings Are Stored in Those Files

Each file is a plain Dart const Map<String, String> of key → translated value. The key is the English source text; the value is the translation for that language.

// lib/lang/app_en.dart
const Map<String, String> enUS = {
  "Home": "Home",
  "Bookings": "Bookings",
  "Save": "Save",
  "Welcome": "Welcome",
  // Parameterized strings use the @placeholder syntax:
  "minimum_amount": "Minimum amount @amount required",
  "discount_off": "Discount (@discount% off)",
};
// lib/lang/app_hi.dart  -> SAME keys, translated values
const Map<String, String> hiIN = {
  "Home": "होम",
  "Bookings": "बुकिंग",
  "Save": "सहेजें",
  "Welcome": "स्वागत है",
  "minimum_amount": "न्यूनतम राशि @amount आवश्यक है",
  "discount_off": "छूट (@discount% छूट)",
};
Golden rule — keep the keys identical:

Every language map must use the exact same keys. The key (the left-hand string) is what the UI looks up. If a key is missing from a language's map, GetX falls back and shows the raw key text for that one string. Add the key to every app_xx.dart file whenever you add a new string.

4. Register the Maps in LocalizationService

lib/services/localization_service.dart extends GetX's Translations class and maps each code to its imported strings map. The code here must match the Code you entered in the Admin Panel (Step 1).

// lib/services/localization_service.dart
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import '../lang/app_en.dart';
import '../lang/app_hi.dart';
import '../lang/app_ar.dart';

class LocalizationService extends Translations {
  static const locale = Locale('en', 'US');      // default locale
  static final locales = [
    const Locale('en'),
    const Locale('hi'),
    const Locale('ar'),
  ];

  @override
  Map<String, Map<String, String>> get keys => {
    'en': enUS,   // from app_en.dart
    'hi': hiIN,   // from app_hi.dart
    'ar': lnAr,   // from app_ar.dart
  };

  void changeLocale(String lang) {
    Get.updateLocale(Locale(lang));  // switches the active language at runtime
  }
}

5. Wire It Into the App (main.dart)

In each app's main.dart, GetMaterialApp is told about the translations and the default/fallback locale:

GetMaterialApp(
  translations: LocalizationService(),         // the maps from Step 4
  locale: LocalizationService.locale,          // Locale('en', 'US')
  fallbackLocale: LocalizationService.locale,  // used if a key/locale is missing
  // ...
);

6. Using a String in the UI

Anywhere in the app, call .tr on the key. GetX looks the key up in the currently active language map and returns the translated value.

// Simple string
Text("Home".tr)
AppButton(text: "Save".tr)

// Parameterized string -> .trParams replaces @placeholders
Text("minimum_amount".trParams({ "amount": "100" }))
// active locale = hi  ->  "न्यूनतम राशि 100 आवश्यक है"

7. How the User Selects a Language

// 1) switch the active language immediately
LocalizationService().changeLocale(selectedLanguage.code);   // Get.updateLocale(...)

// 2) remember the choice for next launch (SharedPreferences)
Preferences.setString(
  Preferences.languageCodeKey,
  jsonEncode(selectedLanguage.toJson()),
);

The Complete Flow (Admin → App UI)

End-to-end:
  1. Admin adds a language (Name + Code) under Admin Panel → Global Settings → Languages → saved to the languages collection.
  2. Developer creates lib/lang/app_<code>.dart in each app with the translated key/value map (same keys as English).
  3. Developer registers that map in localization_service.dart under the matching code.
  4. App starts → fetches the language list from Firestore → the new language now appears on the Language screen.
  5. User selects it → Get.updateLocale() switches the active map → choice saved to SharedPreferences.
  6. Every "key".tr / .trParams() in the UI instantly resolves against the new language map → the whole app re-renders translated.
Quick checklist when adding a new language:

☐ Add the language (Name + Code) in Admin Panel → Global Settings → Languages.
☐ Create app_<code>.dart in all three apps with every key translated.
☐ Import it + add the Locale and keys entry in each app's localization_service.dart.
☐ Make sure the Code in the panel === the code key in LocalizationService (e.g. hi).
☐ Rebuild and run — the new language appears and translates the UI.

Common issues and their solutions.

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 deployment fails

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 to build iOS apps, and it only runs on macOS. Android and Web can be built on Windows or Linux.

Q: Which Firebase plan do I need?

The Blaze plan (pay-as-you-go) is recommended — Cloud Functions, phone auth, and some other features aren't available on the free Spark plan. Blaze still includes a free usage tier.

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

HandyHive is built for Firebase. A different backend would require major code changes.

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: How do I contact support?

Want to pull future HandyHive releases into your own customised project without losing the changes you've made? The cleanest path is to keep your project under Git and treat each new release as another branch you merge in. The notes below cover what to prepare, what to expect, and where our support scope ends.

Note
  1. Take a complete backup of your project before applying any update — we cannot recover changes lost during a merge.
  2. Apply the same procedure separately for each application folder shipped in the package: handyhive_customer/, handyhive_partner/, handyhive_worker/, admin_panel/, and function/.
  3. Don't edit your application package name, bundle ID, or version metadata directly during the merge — these are tied to your release builds on Play Store / App Store and changing them will break in-place updates for existing users.
Warning

Manual updates to HandyHive require working knowledge of Flutter and Firebase. Always back up your project and validate every change in a staging Firebase environment before deploying to production. We can't be held responsible for issues or data loss caused by manual updates — refer to the official Flutter and Firebase documentation when in doubt.

Note — Support Scope

Per Envato's standard support policy, installation, configuration, customisation, and upgrade work are not included in free item support. Free support covers only bugs or errors in the originally delivered code.

The steps on this page are provided as informational guidelines to help you self-serve when bringing a customised project up to the latest release.

Please don't open support tickets for issues encountered during the upgrade process — these fall outside the scope of free item support.

Upgrade via GitHub Desktop — Step by Step

Use GitHub Desktop to keep your customised project on a private branch and merge each new HandyHive release into it without losing your changes. Follow the steps below in order.

Step 1 — Download and install GitHub Desktop

  1. Open https://desktop.github.com/ and download the installer for your OS (Windows or macOS).
  2. Run the installer and complete the standard setup.
  3. Launch GitHub Desktop.
  4. GitHub Desktop installed and launched

Step 2 — Sign in to GitHub

  1. On first launch GitHub Desktop prompts you to sign in. Click Sign in to GitHub.com.
  2. Complete the browser-based sign-in flow and return to GitHub Desktop. Confirm your name and email on the configure-git screen and click Finish.
  3. GitHub Desktop sign-in screen

Step 3 — Open the “Add” menu

  1. Click the Current repository dropdown at the top-left.
  2. In the panel that opens, click the Add dropdown at the top-right.
  3. Current repository dropdown with Add menu open

Step 4 — Create a new repository

  1. From the Add dropdown, choose Create new repository…
  2. Create new repository option

Step 5 — Fill in the repository form

  1. Name: e.g. handyhive-customised.
  2. Local path: browse to the folder that contains your existing HandyHive project.
  3. Leave the other options at their defaults and click Create repository.
  4. Create a new repository form filled in

Step 6 — Commit your existing project as the baseline

  1. GitHub Desktop lists every file in your project under Changes.
  2. Type a commit summary — for example Initial commit — my customised v8.4 build.
  3. Click Commit to main.
  4. Initial commit on main

Step 7 — Publish the repository to GitHub

  1. Click Publish repository at the top of the window.
  2. Tick Keep this code private.
  3. Click Publish Repository.
  4. Publish repository dialog with private ticked

Step 8 — Create a v8.5 branch

  1. Click Current branchNew branch.
  2. Name it v8.5 and click Create branch.
  3. Confirm you are now on the v8.5 branch (shown in the top bar).
  4. Create branch dialog with v8.5

Step 9 — Download the latest HandyHive release

  1. Open your CodeCanyon Downloads page.
  2. Download the HandyHive v8.5 package and extract it to a temporary folder — do not extract it over your existing project.

Step 10 — Replace the code folders on the v8.5 branch

  1. Make sure the v8.5 branch is still active in GitHub Desktop.
  2. From the extracted v8.5 package, copy these folders into your project, replacing the existing ones:
    • handyhive_customer/lib/
    • handyhive_partner/lib/
    • handyhive_worker/lib/
    • admin_panel/lib/
    • function/functions/
  3. Leave everything else untouched — branding, Firebase config files, signing keystore, and platform projects.
  4. Replacing lib folders from v8.5 package

Step 11 — Commit the v8.5 changes

  1. Switch back to GitHub Desktop — the updated files appear under Changes.
  2. Enter the commit summary Upgrade to v8.5.
  3. Click Commit to v8.5.
  4. Commit v8.5 changes

Step 12 — Push the v8.5 branch to GitHub

  1. Click Push origin at the top of the window.
  2. Wait for the push to complete.
  3. Push origin to upload v8.5 branch

Step 13 — Merge v8.5 into main

  1. Switch Current branch back to main.
  2. From the top menu choose BranchMerge into current branch…
  3. Select v8.5 and click Create a merge commit.
  4. Merge v8.5 into main

Step 14 — Resolve conflicts (if any)

  1. If GitHub Desktop reports conflicts, click Open in your editor.
  2. In each conflicted file, look for the markers <<<<<<<, =======, >>>>>>> and keep the correct lines.
  3. Save each file and return to GitHub Desktop — the conflict count drops as files are resolved.
  4. When the count reaches zero, click Continue merge, then Push origin.
  5. Resolve merge conflicts

Step 15 — Apply the changes to your real project

  1. Open GitHub Desktop's History tab and review each commit from the v8.5 merge.
  2. For every change, open the file in your editor side-by-side with your real project.
  3. Copy the changes one by one and paste them into your real project.

Manual Upgrade — Replace the lib Folder

If you'd rather skip Git entirely, you can upgrade by replacing the lib/ folder of each app with the one from the new release. This is faster but loses any customisation you made inside lib/, so review the diff before overwriting.

Important note

While replacing the lib folder manually, do not overwrite firebase_options.dart. Keep your existing Firebase configuration file.

  1. Take a complete backup of your existing project folder (zip the whole thing).
  2. Open your CodeCanyon Downloads page and download the latest HandyHive package. Extract it to a temporary folder — do not extract it over your existing project.
  3. In the extracted package, locate the lib/ folder inside each app:
    • handyhive_customer/lib/
    • handyhive_partner/lib/
    • handyhive_worker/lib/
    • admin_panel/lib/
  4. In your existing project, delete the corresponding lib/ folder for the app you're upgrading — but first back up your existing lib/firebase_options.dart file (you'll restore it in the next step).
  5. Copy the new lib/ folder from the extracted package into the same location in your project.
  6. Restore your own lib/firebase_options.dart over the one shipped in the new release. This file is generated by flutterfire configure against your Firebase project — if you overwrite it with the sample one from the release, your apps will connect to the wrong Firebase.
  7. Re-apply any other customisations you previously made inside lib/ (branding constants, custom screens, etc.) on top of the new files.
  8. Open pubspec.yaml in each app and compare it with the new release. Add any new dependencies introduced in the latest version.
  9. From each app folder, refresh dependencies:
    flutter clean
    flutter pub get
    On macOS, also run pod install --repo-update inside handyhive_customer/ios.
  10. Build and run each app to confirm the upgrade works alongside your customisations.
Warning

The manual method overwrites every file inside lib/. Any changes you made there will be lost unless you re-apply them after the copy. If you've heavily customised lib/, prefer the GitHub Desktop method above — it merges your changes with the new release rather than replacing them.

Version 8.4 11 June 2026 Latest
  • Mobile Number Validation — Added proper validation for mobile number fields across the apps.
  • Chat Seen Status Fixed — Corrected the "seen" indicator behaviour in chat conversations.
  • Language Selection Fixed — Resolved the first-time language selection not applying correctly.
  • App Theme Selection Fixed — Fixed the app theme not being applied/selected properly.
  • Booking Details Phone Format — Corrected the customer phone number format to include the country code on the booking details screen.
  • Dynamic Booking OTP Verification — Made the booking OTP verification flow admin-configurable; when disabled, Start and Complete actions run directly without an OTP dialog.
  • Extra Charge Payment Fixed — Resolved the payment issue that occurred when an extra charge amount was applied to a booking.
  • UI Improvements — Fixed various UI-related issues for a more polished experience.
Version 8.3 26 April 2026
  • Revamped Admin Panel with a more modern and attractive UI design.
  • Updated project to support the latest Flutter version (Flutter 3.41.0).
  • Fixed known bugs to improve overall stability.
  • Enhanced app performance and responsiveness.
  • Upgraded dependencies to the latest compatible versions.
Version 8.2 28 January 2026
  • Minor Issue Fixes — Resolved several UI and functional bugs for improved stability.
Version 8.1 08 November 2025
  • Zone Feature Implemented — Added zone-based operations for better location handling.
  • Minor Issue Fixes — Resolved several UI and functional bugs for improved stability.
  • Enhanced Searching — Improved search functionality for faster and more accurate results.
  • Subscription Issue Fixed — Corrected issues with subscription plan handling and validation.
  • Flutter Updated — Upgraded project to support the latest Flutter version for better performance and compatibility.
Version 8.0 14 April 2025
  • Implemented automatic cancellation for unaccepted service requests after a set duration. If the order was paid online, the amount is refunded automatically upon cancellation.
  • Added report generation functionality for the following modules: Orders, Workers, Job Requests, Users, Subscriptions, Services, Providers, and Payouts.
  • Integrated Subscription module for Providers, enabling subscription-based access and management.
Version 7.0 12 September 2024
  • Added a new feature allowing users to provide services at the store.
  • Implemented a robust support system for users, enabling easy issue reporting and faster response times.
  • Updated all Flutter dependencies to the latest compatible versions.
  • Application now supports and is fully compatible with Flutter version 3.22.3.
  • Resolved various minor bugs and performance issues for a smoother user experience.
Version 6.0 29 June 2024
  • Added animations.
  • Implemented pagination.
  • Integrated search functionality in the admin panel.
  • Added new payment gateways: Paystack, Flutterwave, MercadoPago and PayFast.
  • Updated UI.
  • Fixed minor bugs.
  • Dependencies set to their latest versions.
  • Updated to support the latest Flutter version 3.22.2.
Version 5.0 14 April 2024
  • Added OTP feature for enhanced security.
  • Implemented hourly-based service options.
  • Introduced a “Hold Reason” feature for better transaction tracking.
  • Conducted minor bug fixes and optimizations.
Version 4.0 08 April 2024
  • Implemented dynamic color scheme functionality.
  • Enabled the ability to save multiple addresses within the customer application.
  • Updated the user interface of the admin panel for enhanced usability.
  • Implemented automatic refund to the user's wallet in case of booking cancellation.
  • Enabled access to certain features for customers without requiring them to log in.
  • Conducted minor bug fixes to enhance the overall stability and performance of the application.
Version 3.0 22 February 2024
  • Monthly earnings cap — all applications and admin sites can change their currency symbol.
  • Added search capabilities to the admin sites for VerifyDocuments, Users, Providers, Workers, OrderHistory and JobRequest History.
  • Changed the dependency of flutter_html to flutter_widget_from_html for all applications.
  • Set up partner account deletion and partner data deletion.
  • Added the ability to filter by date on order histories, job requests and history admin sites.
  • Added a partner application with date filter capabilities.
  • Created a job request information page.
Version 2.0 25 January 2024
  • Fixed document verification issue.
  • Resolved home screen load issue.
  • Fixed location permission issue.
  • Upgraded to the latest Flutter version.
  • Updated project dependencies.
  • Minor bug fixes.
Version 1.0 17 January 2024
  • Initial upload.