Android

Car Booking SaaS – Android Apps Documentation

Apps v1.0.0 · needs website v1.7+

Overview

Car Booking is a pair of Android apps for the Car Booking SaaS – Car Rental Management System website: a Driver app for drivers and a Customer app for renters. Rental company owners and staff keep using the website. The apps talk only to your website, so all data stays on your server.

Two apps, one websiteDriver app for the company's drivers, customer app for the renters of every company on your platform.
One app for many companiesRenters find a company by name, QR code or code, so a single Google Play listing serves every rental company on your website.
Own-brand optionA build script makes a separate customer app for ONE company: its own name, icon and package id.
Same rules as the websitePrices, taxes, deposits, cancellation and permissions come from the website's own code.
Push notificationsThrough Firebase: new and cancelled jobs for drivers, booking updates and reminders for customers. Inbox with unread badge.
SecureToken kept in the phone's secure storage; HTTPS only in release builds; optional fingerprint / face / PIN lock in the customer app.

What is in the package

Folder / fileWhat it is
driver_app/Flutter project of the Driver app (package id com.carbooking.driver_app), with its android/ folder ready.
customer_app/Flutter project of the Customer app (package id com.carbooking.customer_app), with its android/ folder and tools/build_branded.py.
docs/mobile-api.mdReference of the website API the apps use (for developers who want to extend them).
README.mdShort overview and quick start.
documentation/This guide.
Required: the apps need Car Booking SaaS v1.7 or newer, installed on a domain with HTTPS (SSL certificate). The website is a separate product.

Features

Driver app

AreaWhat the driver can do
Sign inEmail and password of the driver account created on the website. Stays signed in (token kept in the phone's secure storage).
HomeToday's jobs, the week ahead, money earned and to be paid, and alerts.
JobsJobs for the next days with call the customer and open in maps buttons.
Start and finish a rentalOdometer and fuel level at start and at return; the website closes the contract and works out late and extra-kilometre fees.
PhotosPick-up, return and damage photos, uploaded to the booking (visible to the office and the customer).
BookingsHistory of the driver's bookings with search and filters.
Rental agreementsRead the agreement and sign with a finger.
ExpensesAdd an expense (fuel, parking, toll…) with a photo of the receipt.
EarningsCommission per completed job and the payout history.
Notices & pushOffice notices; push notification when a job is assigned or cancelled.

Customer app

AreaWhat the renter can do
Find a companySearch by name or city, scan the company's QR code, or type the company code. One app can serve many rental companies, or you can build an own-brand app for one company (see Own-brand customer app).
Sign inEmail code, password, or phone SMS code (each method can be switched on or off by the company). New customers are registered on first sign-in.
Search carsPick-up and return date and time, only the free cars with the trip price, sorting (price, seats, name), filters (type, gearbox, fuel) and saved favourites.
Car pagePhotos, extras, pick-up and return places, promo or friend code, notes, price breakdown and the company's rules (online payment, approval, free cancellation).
Book and payBook, then pay on the company's secure payment page (Stripe, PayPal, Paystack, Flutterwave or Razorpay, whichever the company enabled).
My bookingsUpcoming, past and cancelled. Per booking: status, dates, places, extras, money (total, paid, to pay), "show at pick-up" card, pay, extend the rental, rate the rental, invoice (PDF), cancel inside the free window, car photos, deposit and driver details, report a problem, add to calendar.
Home dashboardCurrent trip, countdown to the next trip, directions, amount to pay, book again and offers.
ProfileEdit details, My documents (photograph the licence and ID with expiry date), Rewards (loyalty points, history, friend code, current promo codes), switch company, delete my account.
ContactCall, WhatsApp, email, or a message into the company's inbox; Ask our AI helper when the company has it switched on.
NotificationsInbox (bell) that keeps every message, plus push notifications when a booking is confirmed or cancelled and a reminder the day before pick-up and return.
Comfort & securityLight, dark and automatic appearance; optional fingerprint / face / PIN lock.

Not included

Requirements

Your computer (to build the apps)

WhatVersion / notes
Operating systemWindows 10/11 (64-bit), macOS, or Linux (64-bit)
Flutter SDKLatest stable release (3.27 or newer; tested with 3.47). Includes Dart.
Android StudioLatest version. Gives you the Android SDK, build tools, Java (JDK 17+, bundled) and the emulator.
Android SDKInstalled by Android Studio (SDK Platform, Build-Tools, Command-line Tools, Platform-Tools).
Disk / memoryAbout 10 GB free space, 8 GB RAM or more recommended.
Python 3 with PillowOnly for the own-brand build script (pip install pillow).

Phones that can run the apps

Android 7.0 or newer (the minimum is Flutter's default for the Flutter version you build with).

Accounts

AccountCostNeeded for
Google Play Console$25 one timePublishing on Google Play
Firebase (Google)Free (Spark plan is enough)Push notifications

Website

Car Booking SaaS v1.7 or newer on HTTPS — see Prepare the website.

Install Flutter & Android Studio

  1. Install Android Studio from developer.android.com/studio. Start it once and finish the setup wizard (Standard). Then open Settings → Languages & Frameworks → Android SDK → SDK Tools and tick Android SDK Command-line Tools and Android SDK Platform-Tools. In Plugins, install the Flutter plugin (it adds Dart).
  2. Install Flutter following docs.flutter.dev/get-started/install (choose your operating system → Android). Unzip it to a folder without spaces (e.g. C:\src\flutter or ~/flutter) and add its bin folder to your PATH.
  3. Accept the Android licences and check everything:
    flutter doctor --android-licenses
    flutter doctor
    flutter doctor must show a tick for Flutter and Android toolchain. (Chrome, Xcode and Visual Studio are not needed for Android.)
On Windows, if flutter doctor cannot find Java, set JAVA_HOME to Android Studio's bundled JDK (e.g. C:\Program Files\Android\Android Studio\jbr) or run flutter config --jdk-dir "<that folder>".

Prepare the website

Do this once on the website before building the apps.

  1. Website on HTTPS. Install Car Booking SaaS v1.7 or newer on your domain with an SSL certificate (Let's Encrypt is free). Release builds of the apps refuse plain http://.
  2. Run the update. If you upgraded an existing website, make sure the database update ran (php artisan migrate --force, or the website's update screen). It creates the tables for phones, notifications, customer sign-in codes and photos.
  3. Find your API address. It is your website address followed by /api/mobile/v1, for example https://rent.yourdomain.com/api/mobile/v1. Test it in a browser: https://rent.yourdomain.com/api/mobile/v1/companies?q=a should answer with JSON (a list of companies), and …/api/mobile/v1/company/demo shows one company's name, logo and colour.
  4. Online booking for each company. The customer app needs the company's online booking switched on (owner → Online Booking). The company code is the web address name of that page: …/book/demo means code demo. Owners also find the code, a QR code and a "copy message" button under Mobile apps in their menu.
  5. Customer sign-in. Customers receive a 6-digit code by email, so the company needs working email settings (Settings → Email). The owner can also allow password sign-in and SMS code sign-in (needs the owner's Twilio account). Each method can be switched on or off by the company.
  6. Driver accounts. Create each driver under Driver in the owner's menu. Drivers sign in to the app with that email and password. Set the commission rule on the driver's page to see earnings in the app.
  7. Store links (optional but recommended). After publishing, add the Google Play / App Store links as super admin → Mobile apps. They appear on every company's public "Get our app" page (/book/<code>/app) together with the QR code.
  8. Cron job and queue. The website's cron (php artisan schedule:run every minute) sends the reminders (pick-up, return, payment). For push notifications keep a queue worker running (php artisan queue:work) or set QUEUE_CONNECTION=sync in .env.
  9. Upload size. Photos are sent from the phone: set PHP upload_max_filesize and post_max_size to at least 10M.

Set up the projects

Unlike many Flutter packages, the android/ folder of both apps is already included, with the permissions, app name, icon and Firebase hook applied. There is no setup script.

  1. Unzip the package. It contains driver_app, customer_app and docs; put them in a path without spaces, for example ~/projects/android_app.
  2. Download the libraries for each app:
    cd ~/projects/android_app/driver_app
    flutter pub get
    cd ../customer_app
    flutter pub get
  3. Set your website address. Either edit lib/config.dart in each app:
    static const String apiBase = String.fromEnvironment(
      'API_BASE',
      defaultValue: 'https://your-domain.com/api/mobile/v1',
    );
    or leave the file as it is and add --dart-define=API_BASE=https://your-domain.com/api/mobile/v1 to every flutter run / flutter build command.
  4. Choose your package name. The placeholders are com.carbooking.driver_app and com.carbooking.customer_app. Change them to your own (for example com.acmerentals.driver) before you publish: in android/app/build.gradle.kts (namespace and applicationId) and rename the folder android/app/src/main/kotlin/com/carbooking/driver_app (and the package line in MainActivity.kt) to match.
    The package name can never change after the app is published on Google Play. Use lower case letters, numbers, underscores and dots only.
  5. Open the project in Android Studio (File → Open → the driver_app or customer_app folder) or VS Code.
The customer app can be built for ONE company (no company search). Add --dart-define=COMPANY=demo to the command, or use the build script (Own-brand customer app).

Run on a phone or emulator

On a real phone

  1. On the phone: Settings → About phone, tap Build number 7 times to enable Developer options.
  2. Settings → Developer options → USB debugging: on. Connect the phone with USB and allow the computer.
  3. Check the phone is listed, then run (in the app's folder):
    flutter devices
    flutter run --dart-define=API_BASE=https://your-domain.com/api/mobile/v1

On the emulator

Android Studio → Device Manager → Create device (e.g. Pixel 8, latest system image) → Start. Then flutter run.

Testing against a local website (http)

Debug builds allow plain http:// so you can test against a website on your computer or local network (release builds need HTTPS):

# phone on the same Wi-Fi as your computer (use your computer's IP address)
flutter run --dart-define=API_BASE=http://192.168.1.10/car-booking-saas/main_file/api/mobile/v1

# Android emulator: 10.0.2.2 is your computer
flutter run --dart-define=API_BASE=http://10.0.2.2/car-booking-saas/main_file/api/mobile/v1

Which account to sign in with

AppSign in with
DriverThe email and password of a driver account created on the website (owner → Driver).
CustomerThe company code of a company that has online booking switched on, then any email address: the 6-digit code arrives by email. New emails become customer accounts on first sign-in.

A test APK to share

flutter build apk --debug --dart-define=API_BASE=https://your-domain.com/api/mobile/v1
# file: build/app/outputs/flutter-apk/app-debug.apk

Send this file to testers; they install it after allowing "Install unknown apps". For the store, use a release build (next sections).

Branding & customisation

Changes that need no new build (from the website)

WhatWhere on the website
Company name, logo and colour shown in the customer appOwner → Settings → General (company name, logo) and the website colour. The customer app follows them every time it opens.
Which sign-in methods customers getOwner → Online Booking / Settings (email code, password, SMS code)
Whether the company is listed in the app's searchOwner → Mobile apps → "List my company in the app"
Store links, QR code and company code pageSuper admin / Owner → Mobile apps
Which push messages are sentOwner → Configuration → Email Notification (Push Enable column and "Phone app notifications")

Changes in the code (then build again)

WhatHow
App name under the iconandroid:label in android/app/src/main/AndroidManifest.xml (currently "Car Booking Driver App" and "Car Booking").
Website addressapiBase in lib/config.dart, or --dart-define=API_BASE=… when building.
Fixed company (customer app)--dart-define=COMPANY=your-code when building: the company screen is skipped.
App iconReplace ic_launcher.png in each android/app/src/main/res/mipmap-* folder (mdpi 48, hdpi 72, xhdpi 96, xxhdpi 144, xxxhdpi 192 px) and ic_launcher-playstore.png (512 px) in android/app/src/main/. For the customer app the own-brand script (below) makes all sizes from one logo.
Login logoReplace assets/logo.png (login screen) and assets/mark.png (small mark).
Driver app colourslib/theme.dart.
Texts / translationScreen texts are in lib/screens/. Search for the English text and replace it.

Push notifications (Firebase)

Without this step the apps work and show updates in the inbox, but phones do not get pop-up notifications. Push needs a Firebase project, one file in each app, and one file on the website server.

  1. Go to console.firebase.google.com → Create a project (Google Analytics is not needed).
  2. In the project: Add app → Android, once per app. Android package name: exactly your app ID (applicationId in android/app/build.gradle.kts), for example com.acmerentals.driver and com.acmerentals.customer. SHA-1 is not needed. Click Register app.
  3. Download google-services.json and put it in the app's android/app/ folder. The build picks it up automatically (the Firebase plugin is only switched on when this file exists). Do this for both apps, each with its own file.
  4. Firebase → Project settings → Service accounts → Generate new private key. A JSON file downloads. Keep it secret.
  5. Server: save that JSON file on the website server outside the web folder and put its path in the website's .env:
    FCM_CREDENTIALS=/home/youruser/firebase-service-account.json
    Keep the queue running (php artisan queue:work) or use QUEUE_CONNECTION=sync.
  6. Rebuild the apps, install them on a real phone (push does not work on most emulators), sign in and allow notifications when Android asks (Android 13+).
  7. Test: in the admin panel assign the driver a job. The driver's phone should ring within a few seconds. For the customer app confirm a booking of that customer.
One Firebase project can hold both Android apps and both iPhone apps. The website sends to all of them.

When users are notified

WhoEventOpens
DriverNew job assignedThe job
DriverJob cancelledThe job
CustomerBooking confirmed by the companyThe booking
CustomerBooking cancelled by the companyThe booking
CustomerReminder the day before pick-up and the day before returnThe booking

Every message to a customer is also saved in the in-app inbox (the bell), even when phone notifications are off. The company switches push messages on or off under Configuration → Email Notification (the Push Enable column for driver job alerts and the Phone app notifications card for customer booking updates).

Version numbers

The version of each app is in its pubspec.yaml:

version: 1.0.0+1

Signing key (keystore)

Google Play only accepts apps signed with your own upload key. Create it once (one key can sign both apps):

# macOS / Linux
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload

# Windows (PowerShell)
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload

keytool comes with Java; if it is not found, use the one in Android Studio's jbr/bin folder. Choose a strong password and answer the questions (name, organisation, country).

Keep the .jks file and its password safe and backed up, outside the project folder. Never upload it to Git or share it. (With Play App Signing, a lost upload key can be reset through Google support, but it takes days.)

Tell the build where the key is

In each app create android/key.properties:

storePassword=your-store-password
keyPassword=your-key-password
keyAlias=upload
storeFile=/home/you/upload-keystore.jks

(Windows: storeFile=C:\\Users\\you\\upload-keystore.jks.) Add android/key.properties to .gitignore.

Edit android/app/build.gradle.kts. At the top, after the plugins { … } block:

import java.util.Properties
import java.io.FileInputStream

val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

Inside android { … }, before buildTypes, add a signing config, and use it for release:

    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 {
            signingConfig = signingConfigs.getByName("release")
        }
    }

Replace the existing release { signingConfig = signingConfigs.getByName("debug") } block (it is marked with a TODO) — do not keep both.

Build the release

Make sure the apps point to your https website, then in each app folder:

flutter clean
flutter pub get

# for Google Play (Android App Bundle)
flutter build appbundle --release --dart-define=API_BASE=https://your-domain.com/api/mobile/v1
# file: build/app/outputs/bundle/release/app-release.aab

# optional: an installable APK (direct download, other stores)
flutter build apk --release --dart-define=API_BASE=https://your-domain.com/api/mobile/v1
# file: build/app/outputs/flutter-apk/app-release.apk

If you set the address in lib/config.dart, the --dart-define part can be left out.

Test the release APK on a real phone before uploading (flutter install or copy the APK): sign in, open each screen, take a photo, create a test booking and send a test notification.

Publish on Google Play

Publish the Driver app and the Customer app as two separate store listings.

1. Developer account

Register at play.google.com/console ($25 one time, identity verification).

2. Create the app

Play Console → Create app: app name, default language, App (not game), Free, accept the declarations. Do this once for each app.

3. Store listing (Grow → Store presence → Main store listing)

ItemRequirementSuggestion
App nameMax 30 characters"Acme Rentals" (customer), "Acme Rentals – Driver" (driver)
Short descriptionMax 80 characters"Find a car, book and pay in minutes." / "Your jobs, photos and earnings in one app."
Full descriptionMax 4000 charactersList the features of the app from this guide.
App icon512×512 PNG, 32-bitSame mark as the launcher icon
Feature graphic1024×500 JPG/PNGLogo + a short slogan on your brand colour
Phone screenshots2–8, 16:9 or 9:16, 320–3840 pxCustomer: company, cars, car page, bookings, rewards. Driver: home, job, agreement, earnings
Contact detailsEmail (website and phone optional)Your support email
CategoryAuto & Vehicles or Travel & Local (customer), Business (driver)

Tip: take screenshots on the emulator (camera button in the emulator toolbar) with demo data on your website.

4. App content (Policy → App content)

SectionAnswer
Privacy policyURL of the privacy policy page on your website
App accessAll or some functionality is restricted → add a demo login: for the driver app an email and password; for the customer app the company code and a test email (and how the code or password is obtained)
AdsNo, the apps do not contain ads
Content ratingFill in the questionnaire (Utility / Travel; no violence etc.) → usually "Everyone"
Target audience18 and over (renters must be adults)
Data safetySee Privacy & data safety
Financial featuresNone in the app: payment is on the company's own payment page

5. Upload and release

  1. Testing → Internal testing → Create release → accept Play App Signing → upload app-release.aab → release notes → Save → Review → Start rollout. Add your testers' emails and install through the opt-in link.
  2. Closed testing (required for new personal accounts: 12+ testers, 14 days).
  3. Production → Create release → upload (or promote the tested release) → choose countries → Send for review.
  4. Review usually takes from a few hours to 7 days. You get an email when the app is live.
  5. Then add the store links on the website: super admin → Mobile apps.

Updates

Raise the build number in pubspec.yaml, build a new .aab, and create a new release in Production (or a testing track first). Use staged rollout (e.g. 20 %) for big changes.

Other distribution

The release APK (app-release.apk) can also be offered as a direct download from your website, through an MDM, or on other stores (Amazon Appstore, Samsung Galaxy Store, Huawei AppGallery). Push notifications need Google Play services on the phone (not available on Huawei phones without Google services).

Privacy & data safety

Both stores require a privacy policy URL and a description of the data the apps handle. Publish a privacy policy page on your website (the website's own privacy policy page can be used) and use these answers in Play Console → Data safety:

DataCollectedPurposeNotes
Name, email, phone numberYesAccount management, app functionalityEntered by the company (drivers) or the customer
Driving licence / ID photosYes (optional, customer app)App functionality"My documents" so pick-up is faster
Photos of vehicles and receiptsYes (optional, driver app)App functionalityPick-up, return and damage photos, expense receipts
Signature imageYes (optional, driver app)App functionalityAgreement signing
MessagesYesApp functionality, customer supportContact the company, report a problem, AI helper
Purchase / booking historyYesApp functionalityBookings, payments, loyalty points
Payment infoNo (in the app)—Payment happens on the company's secure payment page
Device / push tokenYesApp functionalityTo send notifications
LocationNo—Directions open the phone's maps app
Analytics, ads, trackingNo—No analytics or advertising libraries
Account deletion: Both stores expect that users can delete their account. The customer app has Profile → Delete my account built in. Drivers are created by the rental company: mention in your privacy policy and review notes that drivers ask the company to remove their account.

Android permissions used

PermissionAppWhy
INTERNETBothTalk to your website
CAMERABothDriver: photos of the vehicle and receipts. Customer: photo of licence / ID and scanning a company QR code
USE_BIOMETRICCustomerOptional fingerprint / face lock
NotificationsBothAndroid 13+ asks the user after sign-in (only when push is set up)

Android settings reference

What is already set in the android/ folder of the apps, for reference or when you change something by hand.

android/app/src/main/AndroidManifest.xml

<manifest ...>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <!-- customer app only -->
    <uses-permission android:name="android.permission.USE_BIOMETRIC"/>
    <application android:label="Car Booking" ...> ... </application>
    <queries>
        <intent><action android:name="android.intent.action.VIEW"/><data android:scheme="https"/></intent>
        <intent><action android:name="android.intent.action.DIAL"/><data android:scheme="tel"/></intent>
        <intent><action android:name="android.intent.action.SENDTO"/><data android:scheme="mailto"/></intent>
    </queries>
</manifest>

android/app/src/debug/AndroidManifest.xml (debug builds only)

<application android:usesCleartextTraffic="true"/>

This is why http:// works while testing but not in release builds.

android/app/build.gradle.kts (Firebase)

// Firebase push: switched on by dropping your google-services.json into android/app/
if (file("google-services.json").exists()) {
    apply(plugin = "com.google.gms.google-services")
}

Code structure

Both apps

PathContents
lib/main.dartStart-up, theme, chooses the sign-in or the main screens
lib/config.dartServer address (API_BASE), fixed company (customer app), app version
lib/api.dartHTTP client: token, JSON, errors, uploads and downloads
lib/push.dartFirebase notifications: permission, registering the phone, opening the right screen
lib/theme.dartColours and styles
lib/format.dartMoney and date helpers
test/Unit tests (flutter test)

Driver app screens (lib/screens/)

login, home, dashboard, jobs, job_detail, agreements, expenses, earnings, more.

Customer app screens (lib/screens/)

company and scan_code (find a company), login, home, dashboard, cars, car_detail, bookings, booking_detail, booking_photos, documents, rewards, profile, contact, assistant (AI helper), notifications, switch_company. Extra files: app_lock.dart (fingerprint / face / PIN), favorites.dart, cars_filter.dart, settings.dart.

Libraries used: Driver — http, flutter_secure_storage, image_picker, url_launcher, intl, firebase_core, firebase_messaging. Customer — the same plus local_auth (app lock) and mobile_scanner (QR codes). No analytics or advertising libraries.

To add a screen: create it in lib/screens/, load data with the client in lib/api.dart, and add the endpoint on the website in routes/api.php (every endpoint is described in docs/mobile-api.md).

Own-brand customer app

By default the customer app is one app for many companies: the renter finds a company by name, QR code or code. A rental company that wants its own app (its own name, icon and store listing, with no company search) can have a copy built just for it.

Apple and Google only accept an own-brand app when the company publishes it from its own developer account. Give the company the generated project (or the build) to submit.

From the customer_app folder (needs Python 3 with Pillow: pip install pillow, and Flutter on the PATH for --build):

python3 tools/build_branded.py \
  --company sunrentals \
  --name "Sun Rentals" \
  --logo logo.png \
  --api https://your-domain.com/api/mobile/v1 \
  --package com.sunrentals.app \
  --build apk
OptionMeaning
--companyThe company code (the web address name, e.g. sunrentals for …/book/sunrentals). The app skips the company screen.
--nameApp name under the icon
--logoPNG with the company's logo or mark (transparent background is best). All app icons and the login logo are made from it.
--apiYour platform's API address
--packageAndroid application id and iPhone bundle id, e.g. com.sunrentals.app (letters, numbers and dots, at least three parts)
--buildapk, appbundle or none (only create the project)
--outFolder for the result (default build_branded/)

The result is a copy of the app in build_branded/<company>/. The original is never changed. A company can add its own store links under Mobile apps in its menu; they replace the platform's links on that company's website.

Updating to a new version

When a new version of the apps is released:

  1. Back up your project folders (driver_app and customer_app), especially your android/ edits (signing, google-services.json), lib/config.dart and assets/.
  2. Update the website first if the release notes say the apps need a newer website version.
  3. Copy the new lib/, pubspec.yaml, test/ and docs/ over your project. Put your own values back into lib/config.dart (or keep using --dart-define=API_BASE=…, which needs no edit).
  4. Run flutter pub get.
  5. Raise the version in pubspec.yaml (see "Version numbers"), build and upload as usual.

Troubleshooting

ProblemSolution
"Flutter is not installed" / flutter: command not foundFlutter's bin folder is not in PATH. Open a new terminal after changing PATH; check with flutter --version.
flutter doctor: Android licences not acceptedflutter doctor --android-licenses and answer y.
"No connection" / "Could not reach the server" on every screenWrong API_BASE, or the website is on http:// (release builds need HTTPS). Open …/api/mobile/v1/companies?q=a in the phone's browser to check.
Emulator cannot reach a local websiteUse 10.0.2.2 instead of localhost.
Customer app: "company not found"Check the code (the last part of …/book/<code>) and that online booking is switched on for that company.
Customer app: the sign-in code never arrivesThe company needs working email settings (and the email may be in spam). Allow password sign-in or SMS sign-in for the company, or check storage/logs/laravel.log.
Driver app: "sign in with a driver account"The account is not a driver (owners, managers and admins use the website) or the password is wrong.
Gradle: "Unsupported class file major version" / Java errorsUse JDK 17 or newer: flutter config --jdk-dir "<Android Studio>/jbr".
Build very slow or out of memoryIn android/gradle.properties set org.gradle.jvmargs=-Xmx4G; close other programs.
Play Console: "signed in debug mode"Complete the signing steps, then build again.
Play Console: "Version code 1 has already been used"Raise the +number in pubspec.yaml.
Play Console: package name already existsChoose another package name (see Set up the projects).
No push notificationsIs google-services.json in android/app/ of that app, matching its applicationId? Is FCM_CREDENTIALS set in the website's .env and the queue running? Was the app rebuilt and notifications allowed on the phone? Is push switched on under Configuration → Email Notification?
Notifications arrive late when the phone is idleBattery optimisation on some brands (Xiaomi, Oppo, Huawei…). Users can set the app to "No restrictions" in battery settings.
Photos fail to uploadRaise PHP upload_max_filesize / post_max_size to 10M+ on the server.
Payment page does not openOnline payment must be enabled and configured for the company on the website (Settings → Payment).
Old logo/colours shownClose and reopen the customer app; it refreshes the company branding on start.

FAQ

Do I need one app per rental company?

No. One customer app serves all companies on your website: renters find the company by name, QR code or code. A company that wants its own listing can have an own-brand build (Own-brand customer app).

Can owners and staff use the apps?

Not in this version. Owners, managers and staff use the website, which is fully mobile friendly. The apps are for drivers and customers.

Where is the data stored?

Only on your website/server. The phone keeps the sign-in token (in secure storage) and a few settings such as saved favourites.

Does the app work without the website?

No, every screen loads from your website's API.

Can I change the server address without a new build?

No, the address is built into the app (API_BASE). Company name, logo and colours are not built in: they come from the website.

How do payments work?

Pay now opens the company's secure payment page in the browser (Stripe, PayPal, Paystack, Flutterwave or Razorpay); card data never passes through the app.

Can I publish the apps under my own name?

Yes — your package name, app name, icon and Google Play developer account.

Do I need a Mac?

No, Android apps build on Windows, macOS and Linux. (The iPhone apps need a Mac, see the iPhone guide.)

Can I give testers the app before it is on Google Play?

Yes: Play Console internal testing, or share an APK.

Can customers delete their account?

Yes: Profile → Delete my account in the customer app.

Support & changelog

Before contacting support, please check the Troubleshooting section and run flutter doctor.

When you contact support, include:

Support covers installation questions, bugs and help with the steps in this guide. Customisations (new features, design changes) are not included in support but can be ordered separately. Create a support ticket here.

Changelog

VersionDateChanges
1.0.0October 2026First release: driver app and customer app. Driver: jobs, start / finish with odometer and fuel, photos, agreements with signature, expenses with receipt, earnings, notices, push notifications. Customer: find a company, email / password / SMS sign-in, car search, booking and payment, my bookings, extend, rate, documents, rewards, messages, AI helper, notifications, app lock, own-brand build script.