Skip to content
All projects
Client project HealthDelivery & commerce

MidGram

Pharmacies and medical reps in one realtime app

An Arabic-first B2B app linking pharmacies and medical reps in Iraq: product posts, orders, realtime chat and in-chat visit appointments on Firebase.

Country
Iraq
Type
Client project
Platforms
Android · iOS
MidGram banner
user roles in one app
2

Overview

MidGram connects both sides of the pharmaceutical supply conversation. Medical representatives publish their products and reach pharmacies; pharmacies discover reps, post what they need, chat directly and book visits.

One app serves both audiences: the user picks a role on first launch and the app switches to a dedicated module for that role. It is Arabic-only and fully RTL, built for the Iraqi market, and was delivered to the client without a public store listing.

The challenge

  1. 01

    Pharmacies and reps coordinated over phone calls and personal messaging apps, where products, orders and visit times got lost.

  2. 02

    The two roles need different home screens, navigation and data, yet share chat, appointments, profile and auth. Two separate apps would double maintenance.

  3. 03

    Messages and appointments must appear in real time on both phones, with unread counters and push notifications.

  4. 04

    The client needed to force an update or enable maintenance mode after release without shipping a build.

Highlights

For pharmacies

  • Home feed of representatives and their product posts, with search.
  • Representative directory and profiles, with the option to report a rep.
  • Create orders with a title, needed medicines and up to 5 images, tracked under My Orders.

For medical representatives

  • Publish product posts with title, description, price and up to 5 images, managed under My Posts.
  • Browse pharmacies and incoming orders.
  • Open a pharmacy's details and start a chat.

Shared and realtime

  • 1-to-1 chat with text and images, unread counters and read receipts.
  • Each participant can delete a conversation on their side only.
  • Visit appointments sent as chat messages with date and time, shown in both users' Reminders calendar and cancellable by either side.
  • FCM push notifications for new messages and appointments.

Platform

  • Role selection, then Google sign-in or email and password, then role-specific sign-up with city lists and unique-username checks.
  • Remote app configuration in Firestore: minimum version with a force-update screen, maintenance mode and store URLs.
  • Deleted-account handling, in-app privacy policy and terms, and WhatsApp support for deactivated accounts.

Signature feature

Two roles, one codebase, one conversation

  • On first launch the user chooses Pharmacy or Representative. A UserRoleService stores the choice, and every later route resolves from it, each role with its own GetX bindings, controllers and bottom navbar.
  • Reps publish products and pharmacies publish orders, each with up to 5 images in Firebase Storage, and each side sees the other's content in its feed.
  • Either side opens a chat. createOrGetChat reuses an existing conversation and reactivates it if one participant had deleted it.
  • A visit appointment is a typed chat message that also writes an appointment document, shown in both users' Reminders; cancelling updates both sides in real time.

Swipe for more

Engineering notes

  1. 01

    Fast splash, parallel init

    Only Firebase, the cache and a few core services start before runApp. Auth, app config and app-init then run in parallel with a short minimum splash, and any failure still navigates forward.

  2. 02

    Role-aware routing

    Auto-login reads the Firebase user, loads the matching profile from pharmacies or representatives and routes to that module. A missing profile falls back to role selection; a deleted account gets its own screen.

  3. 03

    Remote kill-switches

    AppConfigService compares the installed version with app_config in Firestore and can show a blocking force-update or maintenance screen, all without a new release.

  4. 04

    Chat that survives deletes

    Each conversation stores a per-participant status. Deleting hides it only for that user, a new message reactivates it for the recipient, and unread counts are kept per participant.

  5. 05

    Appointments as first-class messages

    An appointment is sent through the chat service, persisted to its own collection and synced to both users' reminder screens through a helper that maps Firestore IDs to local reminders.

  6. 06

    Arabic-first UI

    The whole app runs RTL with Locale('ar'), Cairo typography, Arabic validation messages and Iraqi city lists. Legal pages are built in-app.

Results

  • One Flutter app serving 2 user roles, pharmacies and medical representatives, with shared realtime chat and appointments.
  • Fully serverless on Firebase (Auth, Firestore, Storage, FCM), with remote force-update and maintenance controls.
  • Delivered to the client; no public store listing to cite.

Stack

  • Flutter
  • Dart
  • GetX
  • Firebase Auth
  • Cloud Firestore
  • Firebase Storage
  • FCM
  • Google Sign-In
  • SharedPreferences
  • package_info_plus
  • Arabic RTL