Android

Smart Tenant – Android App Documentation

App v1.0.0 · needs website v3.6+

Overview

Smart Tenant is the Android app for the Smart Tenant property management website. It gives tenants and maintainers (repair staff) everything they need on their phone, while property owners, managers and the owner keep using the website. The app talks only to your website, so all data stays on your server.

White labelYour name, icon, logo and colours. Logo, favicon, title and colours also change live from the website — no new build.
One app for every companyAfter sign-in the app switches to the tenant's company branding, so a single Google Play listing serves all your owners.
Same rules as the websiteEvery action runs the website's own code: permissions, limits and notifications are identical.
Push notificationsThrough Firebase, configured on the website. Inbox with unread badge in the app.
SecureLogin token kept in the phone's secure storage; HTTPS only in release builds; 2-factor login supported.
Ready for Google PlayStep-by-step build, signing and store submission in this guide.

What is in the package

Folder / fileWhat it is
lib/The app's source code (Flutter / Dart).
assets/logo.png (login screen), icon.png and icon_foreground.png (app icon), notification_icon/ (small notification icon).
setup.shOne command that creates the Android project folder with every setting already applied.
pubspec.yamlApp version and the list of libraries.
docs/API.mdReference of the website API the app uses (for developers who want to extend it).
documentation/This guide.
Required: the app needs the Smart Tenant website v3.6 or newer, installed on a domain with HTTPS (SSL certificate). The website is a separate product.

Features

Tenant features

AreaWhat the tenant can do
HomeNext payment and amount due (red when overdue) with Pay now; total paid this year; lease dates and rent (and any scheduled rent change); property, address, unit, rooms, household; security deposit; autopay status; open repairs; polls to answer; documents that expire soon; inspection report waiting for a signature; parking; upcoming events. Quick buttons: Report a problem, Ask the assistant, Visitor pass, Book a facility.
InvoicesOpen / paid / all invoices; invoice details with items, payments, credit notes; online payment (Stripe / Razorpay — opens the website's secure payment page); PDF receipts downloaded and opened on the phone. The invoice refreshes by itself after paying.
RepairsReport a problem with type, description, photo (camera or gallery) and preferred visit day and time slot; follow the status; see the assigned maintainer and "on the way" notice; message the maintainer and office; rate the job when it is completed.
AssistantChat assistant (AI when enabled on the website) that answers questions, can raise a repair request from the conversation, and shows replies from office staff.
Payment historyAll payments grouped by year with totals per year and receipt downloads.
Security depositAmount held, received, deducted, refunded, the unit's required deposit and every entry.
My documentsDocuments on file (ID, insurance, …) with type, expiry date and "expired" / "expires soon" labels; open the file.
InspectionsMove-in, move-out and routine inspection reports room by room with condition, notes and photos; sign the report in the app.
Utility readingsMeter readings for the unit: previous / current reading, usage, rate and amount.
Notice boardNotices from the property manager.
Facility bookingsBook shared facilities (hall, gym, …) by free time slot, see bookings and their approval, cancel.
Visitor passesCreate a pass with visitor name, date, phone, purpose and vehicle; share the pass code; cancel.
PollsVote in property polls and see results when the manager allows it.
AgreementsRead the lease agreement PDF and sign with a finger.
ProfileName, phone, change password, phone notifications on/off, test notification, sign out.

Maintainer features

AreaWhat the maintainer can do
HomeCounts (urgent, pending, in progress, completed this month, hours, new today); today's visits; earnings this month; work queue (most urgent first); preventive maintenance tasks; recent ratings and feedback.
ScheduleThe next 14 days by day (Today, Tomorrow, …): repair visits on the tenant's preferred day and time slot plus preventive tasks; jobs without a set day at the end.
JobsOpen / pending / in progress / completed jobs. Job details: problem, AI summary and priority, photos, address with Directions (maps app), tenant name and Call, earlier repairs at the same unit, messages.
Updates"I'm on my way" (the tenant gets a notification and SMS); change status; enter cost, hours worked and fixed date; add an after photo and an invoice file. Completing the job notifies the tenant.
AccountTrade, properties covered, jobs completed, total hours, total billed, rating, member since; profile, phone notifications, sign out.

Common to both

Owners and managers are directed to the website: the app is for tenants and maintainers.

Requirements

Your computer (to build the app)

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.
Shell for setup.shmacOS / Linux: Terminal. Windows: Git Bash (comes with Git for Windows) or WSL.

Phones that can run the app

Android 7.0 (API 24) or newer — about 98 % of active Android phones. (The exact minimum is Flutter's default; never lower than Android 6.0.)

Accounts

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

Website

Smart Tenant v3.6 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 app.

  1. Website on HTTPS. Install Smart Tenant v3.6+ on your domain with an SSL certificate (Let's Encrypt is free). Release builds of the app 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 and notifications.
  3. Find your API address. Sign in as the owner → Settings → Mobile App. The page shows the address the app needs, which is your website address followed by /api/v1, for example https://app.yourdomain.com/api/v1. Open https://app.yourdomain.com/api/v1/app-config in a browser: you should see JSON with your logo and colours.
  4. Branding. Settings → General (Application Name, logo, favicon) and the theme colour are used by the app's login screen. Each owner's own General settings and theme are used after their tenants sign in.
  5. Accounts to test with. Create (or use) one tenant account and one maintainer account on the website.
  6. Cron job. The website's cron (php artisan schedule:run every minute) sends the reminder notifications (rent due, lease and document expiry).
  7. Upload size. Photos are sent from the phone; set PHP upload_max_filesize and post_max_size to at least 10M.

Set up the project

  1. Unzip the package. It contains the android_app folder; put it in a path without spaces, for example ~/projects/android_app.
  2. Choose your package name. It is your company's reversed domain, e.g. com.acmehomes. The app's ID on Google Play becomes com.acmehomes.smart_tenant.
    The package name can never change after the app is published. Use lower case letters, numbers and dots only.
  3. Run the setup script in the project folder (Git Bash on Windows):
    cd ~/projects/android_app
    chmod +x setup.sh
    ./setup.sh com.acmehomes "Acme Homes"
    It creates the android/ folder and applies everything the app needs:
    • Internet and notification permissions, links to the browser / phone dialer
    • Minimum Android version and the libraries required by notifications
    • Small notification icon and notification channel
    • App name under the icon, app icon from assets/icon.png
    • Downloads the Flutter libraries (flutter pub get)
    You can run it again at any time; it never duplicates settings.
  4. Set your website address in lib/config/app_config.dart:
    static const String appName = 'Acme Homes';
    static const String apiBaseUrl = String.fromEnvironment('API_BASE_URL',
        defaultValue: 'https://app.yourdomain.com/api/v1');
    static const String websiteUrl = 'https://app.yourdomain.com';
  5. Open the project in Android Studio (File → Open → the project folder) or VS Code.
Windows without Git Bash: run the same steps by hand — flutter create . --org com.acmehomes --project-name smart_tenant --platforms android, then apply the Android settings described in Manual Android settings.

How the setup script works

The android/ folder is not included in the package on purpose: every app needs its own permanent package name, so the folder is created on your computer with yours. setup.sh does this in two steps.

Step 1 — Flutter creates the folder

The script runs Flutter's own command:

flutter create . --org com.acmehomes --project-name smart_tenant --platforms android

This builds a standard android/ folder from Flutter's official template with your ID (com.acmehomes.smart_tenant). The app's code in lib/ is not touched.

Step 2 — the script adds this app's settings

Flutter's template is generic, so the script then edits the new files:

FileWhat is added
android/app/src/main/AndroidManifest.xmlInternet and notification permissions, links to the browser and phone dialer, app name, notification icon and notification channel
android/app/build.gradle.ktsMinimum Android version, and the library setting that phone notifications need
android/app/src/main/res/drawable-*/The small white notification icon, copied from assets/notification_icon/
android/app/src/debug/AndroidManifest.xmlAllows http:// in test builds only (release builds need HTTPS)
All icon sizesGenerated from assets/icon.png (dart run flutter_launcher_icons)
LibrariesDownloaded with flutter pub get

Result

android_app/
  android/  <- created, with com.acmehomes.smart_tenant
  lib/      (unchanged)
  assets/
  ...

Every change is also listed in Manual Android settings, for reference or to make them by hand.

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:
    flutter devices
    flutter run

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:

# phone on the same Wi-Fi as your computer (use your computer's IP address)
flutter run --dart-define=API_BASE_URL=http://192.168.1.10/smart-tenant/main_file/api/v1

# Android emulator: 10.0.2.2 is your computer
flutter run --dart-define=API_BASE_URL=http://10.0.2.2/smart-tenant/main_file/api/v1

Sign in with the tenant or maintainer account you created on the website.

A test APK to share

flutter build apk --debug --dart-define=API_BASE_URL=https://app.yourdomain.com/api/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
Logo and name on the login screenOwner → Settings → General (Application Name, Logo)
ColoursOwner → Settings → theme colour
Company logo, name, colours after sign-inEach owner → Settings → General / theme
Push notification setupOwner → Settings → Mobile App

The app checks for changes every time it opens. The look is remembered, so it opens correctly even offline.

Changes in the code (then build again)

WhatHow
App name under the iconSecond argument of setup.sh (run it again), e.g. ./setup.sh com.acmehomes "Acme Homes". Also set appName in lib/config/app_config.dart.
Website addressapiBaseUrl in lib/config/app_config.dart (or --dart-define=API_BASE_URL=… when building).
App iconReplace assets/icon.png (1024×1024 px, your mark on a solid background, no transparency) and assets/icon_foreground.png (1024×1024, same mark on transparent background, mark about 50–60 % of the square). Then run dart run flutter_launcher_icons. The adaptive icon background colour is adaptive_icon_background in pubspec.yaml.
Fallback logoReplace assets/logo.png (used only before the website has answered once).
Fallback coloursbrandColor and brandDarkColor in lib/config/app_config.dart.
"Use the website" link on loginwebsiteUrl in lib/config/app_config.dart.
Texts / translationScreen texts are in lib/screens/. Search for the English text and replace it.

The settings file:

class AppConfig {
  static const String appName = 'Acme Homes';
  static const String apiBaseUrl = String.fromEnvironment('API_BASE_URL',
      defaultValue: 'https://app.yourdomain.com/api/v1');
  static const Color brandColor = Color(0xFF2CA58D);     // buttons, links
  static const Color brandDarkColor = Color(0xFF0A2342); // headings, accents
  static const String logoAsset = 'assets/logo.png';
  static const String websiteUrl = 'https://app.yourdomain.com';
}

Small notification icon

Android shows a white silhouette in the status bar. Replace the five files in assets/notification_icon/ (white shape on transparent background, 24/36/48/72/96 px for mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi) and run ./setup.sh again.

Push notifications (Firebase)

Without this step the app works and shows updates in the bell inbox, but phones do not get pop-up notifications. Everything is configured on the website: no Firebase files inside the app and no new build.

  1. Go to console.firebase.google.com → Create a project (Google Analytics is not needed).
  2. In the project: Add app → Android. Android package name: exactly your app ID, e.g. com.acmehomes.smart_tenant (see applicationId in android/app/build.gradle.kts). App nickname: anything. SHA-1: not needed. Click Register app.
  3. Download google-services.json. Do not put it in the app; skip the remaining Firebase SDK steps.
  4. Firebase → Project settings → Service accounts → Generate new private key. A JSON file downloads (keep it secret).
  5. On your website as the owner: Settings → Mobile App. Open each file in a text editor and paste:
    • the service account key JSON → Firebase service account (lets the website send)
    • the google-services.json content → Android app (google-services.json) (lets the app connect)
    Save. The page shows a tick for each part.
  6. Close and reopen the app, sign in and allow notifications when Android asks (Android 13+).
  7. Test: tenant More → Send a test notification (maintainer: Account). A notification should arrive within seconds. If not, the message on screen tells you what is missing.
The same Firebase project can also hold your iPhone app. The website sends to both.

When users are notified

WhoEventOpens
TenantNew invoice, rent reminderInvoices
TenantPayment received, rent paid automatically (autopay), automatic payment failed, refund or credit issuedInvoices
TenantRepair status changed, maintainer "on the way"Repairs
TenantReply from the office in the assistant chatAssistant
TenantVisitor has arrivedVisitor passes
TenantFacility booking approved / not approvedFacility bookings
TenantNew notice, new pollNotice board / Polls
TenantRental agreement ready to signAgreements
TenantInspection report ready to signInspections
TenantDocument expiring soon, lease ending soon, rent change noticeMy documents / Home
MaintainerNew job assignedJobs

Every notification is also saved in the in-app inbox (the bell), even when phone notifications are off. Each user can switch phone notifications off under More (tenant) or Account (maintainer).

Version numbers

The version is in pubspec.yaml:

version: 1.0.0+1

Signing key (keystore)

Google Play only accepts apps signed with your own upload key. Create it once:

# 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

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 — do not keep both. (Older projects with build.gradle instead of .kts: see Flutter's guide.)

Build the release

Make sure apiBaseUrl points to your https website, then:

flutter clean
flutter pub get

# for Google Play (Android App Bundle)
flutter build appbundle --release
# file: build/app/outputs/bundle/release/app-release.aab

# optional: an installable APK (direct download, other stores)
flutter build apk --release
# file: build/app/outputs/flutter-apk/app-release.apk

You can also pass the address without editing the file: flutter build appbundle --release --dart-define=API_BASE_URL=https://app.yourdomain.com/api/v1.

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

Publish on Google Play

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.

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

ItemRequirementSuggestion
App nameMax 30 characters"Acme Homes – Tenant App"
Short descriptionMax 80 characters"Pay rent, report repairs and stay in touch with your property manager."
Full descriptionMax 4000 charactersList the tenant and maintainer features from this guide.
App icon512×512 PNG, 32-bitSame mark as assets/icon.png
Feature graphic1024×500 JPG/PNGLogo + a short slogan on your brand colour
Phone screenshots2–8, 16:9 or 9:16, 320–3840 pxLogin, tenant home, invoice, repair, maintainer jobs, schedule
Contact detailsEmail (website and phone optional)Your support email
CategoryHouse & Home or Business

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 tenant and a maintainer demo login with instructions ("Sign in with this email and password")
AdsNo, the app does not contain ads
Content ratingFill in the questionnaire (category: Utility/Productivity; no violence etc.) → usually "Everyone"
Target audience18 and over
Data safetySee Privacy & data safety
Government / financial / health appsNot applicable (rent is paid on your website's 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.

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 app handles. Publish a privacy policy page on your website and use these answers in Play Console → Data safety:

DataCollectedPurposeNotes
Name, email, phone numberYesAccount management, app functionalityEntered by the property manager or the user
PhotosYes (optional)App functionalityRepair photos, after photos
Signature imageYes (optional)App functionalityAgreement signing
MessagesYesApp functionality, customer supportRepair messages, assistant chat
Payment infoNo (in the app)—Payment happens on the website's 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: the stores expect users to be able to request deletion of their account. Accounts in this app are created by the property manager, not by the user. State in your privacy policy and store review notes how users ask for deletion (email address of your support or of the property manager).

Android permissions used

PermissionWhy
INTERNETTalk to your website
POST_NOTIFICATIONSShow notifications (Android 13+ asks the user)
Camera / photosThrough the system picker only when the user adds a photo — no permission prompt on modern Android

Manual Android settings

What setup.sh changes, for reference or for doing it by hand.

android/app/src/main/AndroidManifest.xml

<manifest ...>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application android:label="Acme Homes" ...>
        <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_notification"/>
        <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="smart_tenant_default"/>
        ...
    </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>
        ...
    </queries>
</manifest>

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

<application android:usesCleartextTraffic="true"/>

android/app/build.gradle.kts

android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
        ...
    }
    defaultConfig {
        minSdk = maxOf(flutter.minSdkVersion, 23)
        ...
    }
}
dependencies {
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}

Notification icon

Copy assets/notification_icon/drawable-<size>.png to android/app/src/main/res/drawable-<size>/ic_notification.png for mdpi, hdpi, xhdpi, xxhdpi and xxxhdpi.

App icon

dart run flutter_launcher_icons

Code structure

PathContents
lib/main.dartStart-up, theme, chooses login / tenant / maintainer screens
lib/config/app_config.dartWhite-label settings
lib/core/api_client.dartHTTP client: token, JSON, errors, downloads
lib/core/auth_store.dartSign-in state, restores the saved session
lib/core/branding.dartLogo, name and colours from the website
lib/core/push_service.dartFirebase notifications, unread badge, opening the right screen
lib/core/json.dartHelpers to read the API's JSON (money and dates come pre-formatted)
lib/widgets/Shared widgets: loading/error/empty states, paged lists, status chips, brand logo
lib/screens/auth/Login, forgot password, 2-factor code
lib/screens/tenant/All tenant screens
lib/screens/maintainer/All maintainer screens
lib/screens/common/Profile, messages, notifications inbox and settings, in-app banner
docs/API.mdEvery API endpoint with parameters and responses

Libraries used: dio (HTTP), provider (state), flutter_secure_storage (token), firebase_core / firebase_messaging / flutter_local_notifications (push), url_launcher, image_picker, path_provider, open_filex, signature, cached_network_image, flutter_launcher_icons.

To add a screen: create it in lib/screens/…, load data with context.read<ApiClient>().get('/your-endpoint'), and add the endpoint on the website in routes/api.php (see docs/API.md for conventions).

Updating to a new version

When a new version of the app is released:

  1. Back up your project folder (especially android/, lib/config/app_config.dart and assets/).
  2. Update the website first if the release notes say the app needs a newer website version.
  3. Replace lib/, pubspec.yaml, setup.sh, docs/ and documentation/ with the new files. Keep your own android/ folder, your assets/ images and put your values back into lib/config/app_config.dart.
  4. Run ./setup.sh com.yourcompany "Your App Name" again (same values as before). It only adds missing settings and never changes your package name or signing.
  5. Raise the version in pubspec.yaml (see "Version numbers"), build and upload as usual.

Troubleshooting

ProblemSolution
./setup.sh: Permission deniedchmod +x setup.sh, or run bash setup.sh …
"Flutter is not installed"Flutter'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" on every screenWrong apiBaseUrl, or the website is on http:// (release builds need HTTPS). Open …/api/v1/app-config in the phone's browser to check.
Emulator cannot reach a local websiteUse 10.0.2.2 instead of localhost.
"The app is for tenants and maintainers"The account is an owner/manager/admin; use the website or a tenant/maintainer account.
Gradle build fails: "Dependency requires core library desugaring"Run ./setup.sh again (it adds desugaring) or apply the settings in Manual Android settings.
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: "You uploaded an APK or Android App Bundle that was 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 (run setup.sh in a fresh copy with the new name).
No notificationsSettings → Mobile App shows three ticks? Package name in Firebase matches applicationId? App reopened after pasting? Notifications allowed in the phone's settings? Use "Send a test notification" — it shows the reason.
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 owner on the website.
Old logo/colours shownClose and reopen the app; it refreshes branding on start.

FAQ

Do I need one app per property owner?

No. One app serves all companies on your website; after sign-in it shows the tenant's company branding.

Can owners or managers use the app?

Not in this version. They are directed to the website, which is fully mobile friendly.

Where is the data stored?

Only on your website/server. The phone keeps the login token (in secure storage) and the last branding.

Does the app work without the website?

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

Can I change the API without a new build?

The website address is built into the app. Branding and push settings are not — they come from the website.

How do payments work?

Pay now opens the website's secure payment page (Stripe/Razorpay) in the browser; card data never passes through the app. This is allowed by both stores because rent is a real-world service.

Can I publish the app under my own name?

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

Do I need a Mac?

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

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

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

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.

Changelog

VersionDateChanges
1.0.0October 2026First release: tenant and maintainer apps, online payments, repairs with photos, assistant, agreements and inspections signing, deposit, documents, utility readings, notices, polls, bookings, visitor passes, schedule, push notifications and inbox, dynamic branding.