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.
What is in the package
| App | Folder | Package name | For |
|---|---|---|---|
| FSM Technician | technician_app/android_app/ | com.smartfsm.fsm_technician | Field staff (users of type employee) |
| FSM Client | client_app/android_app/ | com.smartfsm.fsm_client | Your customers (users of type client) |
Inside each folder:
| Folder / file | What 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.yaml | The website API the app uses (for developers who want to extend it). |
pubspec.yaml | App version and the list of libraries. |
documentation/ | This guide. |
Features
FSM Technician
| Area | What the technician can do |
|---|---|
| Home | Today's jobs, overdue alert, next job, shift clock, quick actions and the AI plan for the day (when AI is on for the company). |
| Jobs | Today / Open / Done tabs, search, calendar view, QR scan of equipment labels. |
| Job | Client 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). |
| Time | Clock in / out with a running timer, shift history, trips (mileage), time-off requests. |
| Inbox | Push notifications for new and changed jobs that open the right job. |
| Offline | Jobs cached; every change is queued and uploaded in order when online (More → Waiting to upload). |
FSM Client
| Area | What the customer can do |
|---|---|
| Home | Amount due, "technician is on site", overdue invoices, estimates waiting, next visit, jobs to rate, quick actions. |
| Services | New service request (description, equipment, urgency, preferred day and time, up to 5 photos, saved and sent later if offline); request and job lists. |
| Job | Status, progress timeline, who is coming and when, work and parts done, before / after photos, rating. |
| Billing | Estimates: 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). |
| Equipment | My equipment with service history and warranty, QR scan, service contracts. |
| Inbox | Push notifications for estimates, invoices, visits and finished jobs. |
Common to both
- Sign-in with email and password, two-factor code, and biometric lock.
- Company code, QR code and invite-link sign-in with the company's branding.
- Inbox, profile, password change, offline queue.
Requirements
Your computer (to build the app)
| Item | Needed |
|---|---|
| System | Windows 10/11, macOS or Linux |
| Flutter SDK | Stable channel, Dart 3.13 or newer (sdk: ^3.13.5 in pubspec.yaml) |
| Android Studio | With the Android SDK, platform tools and a recent JDK |
| Free disk space | About 10 GB |
Phones that can run the app
Android 6.0 (API 23) or newer.
Accounts
- Google Play Console developer account (one-time fee) to publish.
- Firebase project (free) if you want push notifications.
Website
Smart FSM SaaS v2.0 or newer on HTTPS, with the migrations run (php artisan migrate).
Install Flutter & Android Studio
- Install Flutter from docs.flutter.dev/get-started/install and add it to your PATH.
- Install Android Studio and, in SDK Manager, the latest Android SDK, platform tools and command-line tools.
- Accept the licences and check everything:
Every line for Flutter and Android should have a green tick.flutter doctor --android-licenses flutter doctor
Prepare the website
- 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). - Make sure the site opens on HTTPS and
APP_URLin.envis the real address. - 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.
- 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.
- For photos: set
upload_max_filesize = 12Mandpost_max_size = 40Minphp.ini(a request can carry 5 photos).
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:
android/app/build.gradle.kts:namespaceandapplicationId- the folder
android/app/src/main/kotlin/…if you rename the package
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
- On the phone: Settings → About → tap Build number 7 times, then turn on USB debugging in Developer options.
- Connect it with a cable and allow the computer.
- 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)
| What | Where |
|---|---|
| Company logo, name, colour, welcome text | Owner → Settings → Branding & Mobile App. The app shows them before sign-in and after. |
| Company code, invite link, QR code | Same page. The invite page /join/<code> has an Open the app button for each app. |
| Store links, minimum version, maintenance, per-company access | Super admin → Mobile Apps |
| Which tabs the client sees | Owner'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)
- App icon: replace
assets/icon.pngandassets/icon_foreground.png, thendart run flutter_launcher_icons. - App name under the icon:
android:labelinandroid/app/src/main/AndroidManifest.xml. - Default brand colour:
defaultBrandColorinlib/util/theme.dart(used until a company is chosen). - Invite links that open the app:
fsmtech://join/<code>andfsmclient://join/<code>work out of the box. To make normalhttps://your-server/join/<code>links open the app too, add anintent-filterwithandroid:autoVerify="true"for your host and put anassetlinks.jsonat/.well-known/.
Push notifications (Firebase)
Optional. Without it everything works and the in-app inbox still fills up; only the phone pop-ups are missing.
- Create a project in the Firebase console and add two Android apps with the package names of the Technician and Client apps.
- Download each
google-services.jsonand put it in<app>/android_app/android/app/. The build switches push on only when the file exists. - 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 - 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.
- AI follows the subscription plan: if the plan has no AI, the AI buttons are hidden.
- There is a daily request limit per company.
- The photo check needs an AI service that can read pictures.
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
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
- Developer account: register at play.google.com/console.
- Create the app: name (FSM Technician / FSM Client), language, free, accept the declarations.
- Store listing: short and full description, icon 512×512, feature graphic 1024×500 and phone screenshots (your
docs/screenshots/folder has sample pictures). - App content: privacy policy URL, data safety form (see Privacy & data safety), ads: none, target audience.
- Test accounts: in App access give Google a demo account (employee for the Technician app, client for the Client app) and the company code.
- 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:
| Data | Why |
|---|---|
| Name, email, phone, company | Account 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 signatures | Job evidence and estimate approval, uploaded to your website |
| Microphone and speech (Technician only) | Dictate job notes |
| Device push token | Send 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
| Permission | App | Used for |
|---|---|---|
INTERNET | Both | Talk to your website |
POST_NOTIFICATIONS | Both | Push notifications |
USE_BIOMETRIC | Both | Fingerprint / face lock |
CAMERA | Both | Photos and QR scan |
ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | Technician | GPS check-in |
RECORD_AUDIO | Technician | Voice 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
- Update the website first (apps are only compatible with a website of the same or a newer version).
- Back up your own changes, unzip the new package and copy your changes back (
lib/, icon, package name,key.properties,google-services.json). - Run
flutter pub get, raise the build number and build again.
Troubleshooting
| Problem | What 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 upload | Raise upload_max_filesize and post_max_size in php.ini. |
| No push notifications | Check FCM_CREDENTIALS on the server and google-services.json in the app; sign in again on the phone. |
| Website error 500 after update | Run php artisan migrate on the website. |
flutter pub get fails | Update Flutter (flutter upgrade) so Dart 3.13 or newer is installed. |
| Release build is rejected by Google Play | It 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
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | October 2026 | First 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. |