Android

Smart FSM – Android App Documentation

Apps v1.0.0 · needs website v2.0+

Overview

Smart FSM Mobile Apps are two Android apps for the Smart FSM SaaS field service website: FSM Technician for your field team and FSM Client for your customers. Owners, managers and the super admin keep using the website. The apps talk only to your website, so all data stays on your server.

One app for every companyOne published build serves all your owners. People enter the company code, scan its QR code or open an invite link, and the app shows that company's logo and colour.
Same rules as the websiteEvery action runs the website's own code: permissions, plan limits, signature rules and notifications are identical.
Works offlineJobs are cached; check-ins, photos, signatures, notes and clock in/out are saved on the phone and uploaded in order when the connection returns.
Push notificationsThrough Firebase, configured on the website. Inbox with unread badge in the app.
SecureLogin token in the phone's secure storage; HTTPS only in release builds; two-factor and fingerprint lock supported.
Ready for Google PlayStep-by-step build, signing and store submission in this guide.

What is in the package

AppFolderPackage nameFor
FSM Techniciantechnician_app/android_app/com.smartfsm.fsm_technicianField staff (users of type employee)
FSM Clientclient_app/android_app/com.smartfsm.fsm_clientYour customers (users of type client)

Inside each folder:

Folder / fileWhat it is
lib/The app's source code (Flutter / Dart): api/, state/, util/, screens/, widgets/.
android/The Android project, already set up (permissions, icons, links, signing hooks).
assets/icon.png and icon_foreground.png (app icon).
test/, tool/Automated tests and the script that makes store screenshots.
docs/openapi.yamlThe website API the app uses (for developers who want to extend it).
pubspec.yamlApp version and the list of libraries.
documentation/This guide.
Required: the apps need Smart FSM SaaS v2.0 or newer installed on a domain with HTTPS (SSL certificate). The website is a separate product.

Features

FSM Technician

AreaWhat the technician can do
HomeToday's jobs, overdue alert, next job, shift clock, quick actions and the AI plan for the day (when AI is on for the company).
JobsToday / Open / Done tabs, search, calendar view, QR scan of equipment labels.
JobClient and site details with call, email and navigate; GPS check-in / check-out; checklist; parts used (stock is deducted); equipment service history; before / after photos; notes with voice dictation and AI tidy-up; AI photo check; client signature; hold / start; complete job (the company's rules apply: signature required, locked statuses, automatic invoice).
TimeClock in / out with a running timer, shift history, trips (mileage), time-off requests.
InboxPush notifications for new and changed jobs that open the right job.
OfflineJobs cached; every change is queued and uploaded in order when online (More → Waiting to upload).

FSM Client

AreaWhat the customer can do
HomeAmount due, "technician is on site", overdue invoices, estimates waiting, next visit, jobs to rate, quick actions.
ServicesNew service request (description, equipment, urgency, preferred day and time, up to 5 photos, saved and sent later if offline); request and job lists.
JobStatus, progress timeline, who is coming and when, work and parts done, before / after photos, rating.
BillingEstimates: approve with a drawn signature or decline. Invoices: lines, tax, credit, payments, balance, pay online (opens the company's secure payment page, already signed in).
EquipmentMy equipment with service history and warranty, QR scan, service contracts.
InboxPush notifications for estimates, invoices, visits and finished jobs.

Common to both

Requirements

Your computer (to build the app)

ItemNeeded
SystemWindows 10/11, macOS or Linux
Flutter SDKStable channel, Dart 3.13 or newer (sdk: ^3.13.5 in pubspec.yaml)
Android StudioWith the Android SDK, platform tools and a recent JDK
Free disk spaceAbout 10 GB

Phones that can run the app

Android 6.0 (API 23) or newer.

Accounts

Website

Smart FSM SaaS v2.0 or newer on HTTPS, with the migrations run (php artisan migrate).

Install Flutter & Android Studio

  1. Install Flutter from docs.flutter.dev/get-started/install and add it to your PATH.
  2. Install Android Studio and, in SDK Manager, the latest Android SDK, platform tools and command-line tools.
  3. Accept the licences and check everything:
    flutter doctor --android-licenses
    flutter doctor
    Every line for Flutter and Android should have a green tick.

Prepare the website

  1. Update the website to Smart FSM SaaS v2.0 or newer and run php artisan migrate. This adds the tables the apps need (tokens, devices, job notes, request photos).
  2. Make sure the site opens on HTTPS and APP_URL in .env is the real address.
  3. As super admin, open Mobile Apps and fill in the store links and the minimum app version. You can also switch the apps off for one company or for maintenance.
  4. As owner, open Settings → Branding & Mobile App: set the company code, logo and colour. Your invite link, QR code and store buttons appear on your public website.
  5. For photos: set upload_max_filesize = 12M and post_max_size = 40M in php.ini (a request can carry 5 photos).
The company code is the short code staff and customers type once in the app. If you change it, old QR codes and invite links stop working.

Open the project

Unlike a bare Flutter source package, the Android project is already included, so there is no setup script. Unzip, then in each app folder:

cd technician_app/android_app      # or client_app/android_app
flutter pub get

The identifiers are com.smartfsm.fsm_technician and com.smartfsm.fsm_client. Change them to your own before you publish:

Point the app at your website

Give the website address when you build; it is then fixed in the app:

flutter run --dart-define=API_BASE_URL=https://your-company.example

If you leave it out, the sign-in screen asks for the server address, which is handy while testing.

Run on a phone or emulator

On a real phone

  1. On the phone: Settings → About → tap Build number 7 times, then turn on USB debugging in Developer options.
  2. Connect it with a cable and allow the computer.
  3. Check flutter devices, then:
    flutter run --dart-define=API_BASE_URL=https://your-company.example

On the emulator

Create a device in Android Studio → Device Manager, start it, then run flutter run.

Testing against a local website (http)

Debug builds accept plain http://. From the Android emulator, your computer is 10.0.2.2:

flutter run --dart-define=API_BASE_URL=http://10.0.2.2/product/smart-fsm/smart-fsm/main_file

Release builds always require HTTPS.

A test APK to share

flutter build apk --release --dart-define=API_BASE_URL=https://your-company.example

The file is in build/app/outputs/flutter-apk/app-release.apk.

Company code & branding

Changes that need no new build (from the website)

WhatWhere
Company logo, name, colour, welcome textOwner → Settings → Branding & Mobile App. The app shows them before sign-in and after.
Company code, invite link, QR codeSame page. The invite page /join/<code> has an Open the app button for each app.
Store links, minimum version, maintenance, per-company accessSuper admin → Mobile Apps
Which tabs the client seesOwner's visible modules (requests, estimates, invoices, equipment, contracts)

The app sends X-App-Version; the website answers 426 update_required below the minimum version, 503 maintenance during maintenance and 403 app_disabled when the company's apps are switched off.

Changes in the code (then build again)

Push notifications (Firebase)

Optional. Without it everything works and the in-app inbox still fills up; only the phone pop-ups are missing.

  1. Create a project in the Firebase console and add two Android apps with the package names of the Technician and Client apps.
  2. Download each google-services.json and put it in <app>/android_app/android/app/. The build switches push on only when the file exists.
  3. On the website: Firebase console → Project settings → Service accounts → Generate new private key. Save the JSON on the server and set in .env:
    FCM_CREDENTIALS=/full/path/to/service-account.json
  4. Build again and sign in once; the phone registers itself.

When users are notified

A push is sent for every inbox item: job assigned or changed, estimate or invoice created, technician arrived, job completed. Phones that no longer exist are removed automatically.

AI features

The AI features in the apps (AI plan for the day, tidy up notes, photo check) use the AI service the owner connects on the website under Settings → AI (OpenAI, Anthropic Claude, Google Gemini or any compatible service). The key is stored encrypted on the server; the app never sees it.

Version numbers

Set the version in pubspec.yaml:

version: 1.0.0+1

1.0.0 is the version people see; +1 is the build number. Increase the build number for every upload to Google Play.

Signing key (keystore)

Create your key once and keep it safe (back it up; if you lose it you cannot update the app).

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

Tell the build where the key is

Create android/key.properties in each app (it is git-ignored):

storePassword=your-password
keyPassword=your-password
keyAlias=upload
storeFile=/full/path/to/fsm.jks
Without this file, release builds are signed with the debug key. They install for testing but Google Play will not accept them.

Build the release

flutter build appbundle --release --dart-define=API_BASE_URL=https://your-company.example

The file is build/app/outputs/bundle/release/app-release.aab. Do this in both app folders.

Publish on Google Play

  1. Developer account: register at play.google.com/console.
  2. Create the app: name (FSM Technician / FSM Client), language, free, accept the declarations.
  3. Store listing: short and full description, icon 512×512, feature graphic 1024×500 and phone screenshots (your docs/screenshots/ folder has sample pictures).
  4. App content: privacy policy URL, data safety form (see Privacy & data safety), ads: none, target audience.
  5. Test accounts: in App access give Google a demo account (employee for the Technician app, client for the Client app) and the company code.
  6. Upload: Testing → Internal testing → create release → upload the .aab → roll out. After testing, promote to Production.

Updates

Raise the version, build a new bundle and upload it as a new release.

Privacy & data safety

You publish the apps, so you are responsible for the store forms. What the apps handle:

DataWhy
Name, email, phone, companyAccount and job contact details
Location (Technician only)Record GPS check-in and check-out at a job; only when the technician taps the button
Photos and signaturesJob evidence and estimate approval, uploaded to your website
Microphone and speech (Technician only)Dictate job notes
Device push tokenSend notifications

All data is sent to your website over HTTPS. The apps contain no ads and no third-party analytics. Users can ask the company to delete their data.

Android permissions used

PermissionAppUsed for
INTERNETBothTalk to your website
POST_NOTIFICATIONSBothPush notifications
USE_BIOMETRICBothFingerprint / face lock
CAMERABothPhotos and QR scan
ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATIONTechnicianGPS check-in
RECORD_AUDIOTechnicianVoice dictation

Code structure

lib/
  main.dart, config.dart, core.dart   start-up, app settings, one import for the shared code
  api/        API client, repositories and models (jobs, invoices, users ...)
  state/      sign-in, offline queue, cache, connectivity, push, local database
  util/       theme, formatting, GPS helper, app config
  screens/    every screen (home, jobs, billing ... plus login, lock, inbox and More)
  widgets/    reusable pieces (shell with bottom bar, cards, signature pad, media picker)
test/         unit and screen tests (run offline with a fake server)
tool/         screenshots for the stores (tool/screenshots.sh)
docs/         API contract (openapi.yaml) and screenshots

The Android and iPhone projects of the same app share the same lib/. If you change one, make the same change in the other. mobile_app/check-sync.sh tells you if they drifted apart. Run the tests with flutter test and the checks with flutter analyze.

Updating to a new version

  1. Update the website first (apps are only compatible with a website of the same or a newer version).
  2. Back up your own changes, unzip the new package and copy your changes back (lib/, icon, package name, key.properties, google-services.json).
  3. Run flutter pub get, raise the build number and build again.

Troubleshooting

ProblemWhat to do
"Company not found"Check the code, and that the owner's website is reachable on HTTPS from the phone.
"Could not reach the server"Check API_BASE_URL, SSL certificate and that /api/v1 opens on the website. Debug builds may use http://, release builds need HTTPS.
"Update required" / "Maintenance"Super admin → Mobile Apps: lower the minimum version, or turn maintenance off.
"Apps are switched off for your company"Super admin → Mobile Apps → enable the company.
Photos fail to uploadRaise upload_max_filesize and post_max_size in php.ini.
No push notificationsCheck FCM_CREDENTIALS on the server and google-services.json in the app; sign in again on the phone.
Website error 500 after updateRun php artisan migrate on the website.
flutter pub get failsUpdate Flutter (flutter upgrade) so Dart 3.13 or newer is installed.
Release build is rejected by Google PlayIt was signed with the debug key: create android/key.properties.

FAQ

Do I need to publish a separate app for each company?

No. One build of each app serves every company; people choose theirs with the company code.

Can the apps work without the website?

No. They are companions to the Smart FSM SaaS website and use its API.

Can I publish the apps under my own name?

Yes: your package name, app name, icon and store account.

Do I need a Mac?

No, Android apps build on Windows, macOS and Linux.

Can I give testers the app before it is in the store?

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

Is a payment taken inside the app?

No. The app opens the company's secure payment page in the browser; card data never passes through the app.

Support & changelog

Before contacting support, check Troubleshooting and run flutter doctor -v.

When you contact support, include: your purchase code, the app version (pubspec.yaml) and website version, the output of flutter doctor -v, the exact error message or a screenshot, and what you did just before the problem.

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

Changelog

VersionDateChanges
1.0.0October 2026First release: FSM Technician and FSM Client apps. Jobs, GPS check-in, photos, signatures, time and trips, offline mode, service requests, estimate approval, online payment, equipment, push notifications and inbox, company code / QR sign-in with company branding, AI plan for the day.