Files
Ontime/ORDERING_WORKFLOW.md
2026-03-11 15:29:37 +07:00

7.0 KiB
Raw Permalink Blame History

OnTime Ordering Workflow & Firebase Alignment

Order flow (User → Driver → Tujuan)

  1. User: Set jemput (pickup) In RideCarActivity, user sets pickup via map/Places (pickUpText, pickUpLatLang).
  2. User: Set tujuan (destination) User sets destination (destinationText, destinationLatLang). Route and price are calculated.
  3. User: Set payment Cash or wallet (checkedpaywallet, cashpayment / walletpayment).
  4. Search driver GetNearRideCarRequestJson / GetNearRideCarResponseJson loads nearby drivers; driverAvailable is used for FCM.
  5. User: Order sendRequestTransaksi() calls backend, then fcmBroadcast() sends FCM to each driver token via backend notification/send_generic.
  6. Driver: Bid or auto bid Driver receives FCM in MessagingService (type=1), opens NewOrderActivity. Manual: tap "order"; Auto: getaccept(true) after 2s if setting is ON.
  7. Driver: Accept getaccept() calls backend accept, then sends FCM to user token (regid) with OrderFCM (response="2", type=1, id_driver, id_transaksi).
  8. User: Driver accepted User app MessagingService gets type=1, response="2", posts DriverResponse via EventBus; RideCarActivity.onMessageEvent starts ProgressActivity (response "2").
  9. Progress (until tujuan) User stays in ProgressActivity; driver in OrderFragment can tap "finish" (start) then "finish" (arrive). Each action: driver calls backend (startrequest / finishrequest), then FCM to user with response "3" (start) or "4" (finish/tujuan).
  10. User: Start / Finish MessagingService parses type=1 and response "3"/"4", posts DriverResponse; ProgressActivity receives via EventBus or broadcast, orderHandler() updates status (e.g. "driver start", "finish/tiba di tujuan").

Test backend API

To test backend, use endpoint: apitest.semestaterpadu.my.id

All apps and the backend panel use the same test API base URL:

Component Config location Base URL API base
User app OnTime_User_liveConstants.java https://apitest.semestaterpadu.my.id/ .../api/
Driver app OnTime_Driver_liveConstants.java https://apitest.semestaterpadu.my.id/ .../api/
Backend backendpanel/application/config/config.php$config['base_url'] https://apitest.semestaterpadu.my.id/ same

Example test endpoints:

  • Base: https://apitest.semestaterpadu.my.id/
  • API (login, transaksi, etc.): https://apitest.semestaterpadu.my.id/api/
  • FCM send: POST https://apitest.semestaterpadu.my.id/api/notification/send_generic

Firebase: same project for User, Backend, Driver

  • Backend Single FCM project: uses fcm_v1_helper (HTTP v1) with service account (e.g. FCM_CREDENTIALS_PATH / FCM_PROJECT_ID). All sends go through backend api/notification/send_generic (POST).
  • User app Receives FCM via FirebaseMessagingService; sends by calling same backend Constants.CONNECTION + "notification/send_generic" with target = driver token and data = DriverRequest (order offer).
  • Driver app Receives FCM via FirebaseMessagingService; sends by calling same backend Constants.CONNECTION + "notification/send_generic" with target = user token and data = OrderFCM (accept/start/finish).

Both apps use the same BASE_URL (e.g. https://apitest.semestaterpadu.my.id/) and same endpoint, so they share the same Firebase project and backend.

FCM type and payload alignment

Type Meaning Sender Receiver Key payload
1 Order User→Driver: DriverRequest (offer); Driver→User: OrderFCM (accept/start/finish/cancel) Both id_transaksi, id_driver, response ("2"/"3"/"4"/"5"), plus offer fields for driver
2 Chat User/Driver User/Driver chat fields
3 Other Backend User/Driver title, message
4 Other2 Backend User/Driver title, message

Backend send_generic_to_token / send_generic_to_topic flatten data and stringify values so FCM receives a flat string map.

Driver & merchant matching: purely GPS (no region)

  • Driver nearby (list_ride / list_car): Uses only real GPS driver position from config_driver (updated by driver apps update_location) and user/customer position from the request. No region/wilayah is used. Radius is fitur.jarak_minimum (km), with a minimum of 10 km.
  • Merchant nearby: Uses only real GPS merchant.latitude_merchant, merchant.longitude_merchant and users lat/long. No region filter. Distance cap is fitur.jarak_minimum.

Drivers wilayah (partner_region) is only used in the admin panel for display; it is not used when finding nearby drivers or merchants for the user.


"Tidak ada pengemudi di sekitar Anda" checklist

If the user always sees "Maaf, tidak ada pengemudi di sekitar Anda" even when a driver is close:

  1. Driver must be "online" In the driver app the driver must be in "online" / status 1 mode. The backend only returns drivers where config_driver.status = '1'.
  2. Driver location The driver app sends location via driver/update_location. Ensure the driver has opened the app and location permission is granted so config_driver has recent latitude/longitude.
  3. Backend radius The backend uses fitur.jarak_minimum (km). A minimum radius of 10 km is now applied so that small values in the admin panel (e.g. 12 km) still show drivers within 10 km. Admin can set Services → jarak_minimum to a larger value (e.g. 15 or 20 km) if needed.
  4. User app If the first fetch was slow or location was not ready, the user can tap Order anyway: the app will refetch nearby drivers once (using pickup or last location) and then either place the order or show the message.

Fixes applied

  • Backend: Implemented send_generic_to_token and send_generic_to_topic in Notification_model using fcm_v1_send; controller loads fcm_v1_helper so generic FCM from both apps works.
  • User MessagingService: Null-safe handling for getData() and type; broadcast bundle now includes code, response, id_transaksi, id_driver so ProgressActivity can update when driver sends start/finish.
  • ProgressActivity: BroadcastReceiver only applies updates when id_transaksi matches; updates local response and calls orderHandler(code) so status and flow (e.g. sampai tujuan) stay correct.
  • Driver MessagingService: Null-safe handling for getData(), type, and harga to avoid NPE/crash on malformed FCM.
  • "No driver near you": Backend get_driver_ride now uses a minimum radius of 10 km (GREATEST(COALESCE(f.jarak_minimum, 10), 10)) so drivers within 10 km are found even if the fiturs jarak_minimum is set very small. User app: when the user taps Order and the driver list is empty, the app refetches nearby drivers once (using pickup or last location) and then proceeds or shows the message.