Kategori: Programming | Perkiraan waktu baca: 9 menit
Sejauh ini saya banyak bahas proyek web (Next.js, Supabase) dan automasi (WhatsApp Bot, Apps Script). Kali ini saya mau cerita proyek di ranah berbeda: JasaKu, aplikasi mobile marketplace on-demand yang saya bangun pakai Flutter — semacam platform yang mempertemukan penyedia jasa (tukang, teknisi, dll) dengan orang yang butuh jasa itu, mirip konsep gig-economy app.
Kenapa Flutter?
Untuk aplikasi mobile yang perlu jalan di Android dan iOS sekaligus dengan resource tim kecil (dalam kasus ini, cuma saya sendiri), Flutter jadi pilihan yang masuk akal:
- Satu codebase, dua platform — nggak perlu maintain kode Kotlin/Swift terpisah
- Performa mendekati native — beda dengan React Native yang masih ada JS bridge, Flutter compile langsung ke native code
- Ekosistem widget yang lengkap — mempercepat development UI yang kompleks seperti marketplace app
Struktur Fitur Utama
JasaKu punya beberapa peran user yang berbeda dalam satu aplikasi:
- Customer — cari dan pesan jasa
- Provider — penyedia jasa yang menerima order
- Admin — kelola verifikasi provider dan monitoring transaksi
Arsitektur State Management
Untuk aplikasi dengan kompleksitas seperti ini, pemilihan state management itu krusial. Saya pakai Riverpod karena lebih testable dan scalable dibanding setState biasa atau bahkan Provider versi lama:
final orderListProvider = StateNotifierProvider<OrderListNotifier, List<Order>>((ref) {
return OrderListNotifier(ref.read(apiServiceProvider));
});
class OrderListNotifier extends StateNotifier<List<Order>> {
final ApiService _apiService;
OrderListNotifier(this._apiService) : super([]);
Future<void> fetchOrders(String userId) async {
final orders = await _apiService.getOrders(userId);
state = orders;
}
void updateOrderStatus(String orderId, OrderStatus newStatus) {
state = [
for (final order in state)
if (order.id == orderId) order.copyWith(status: newStatus) else order
];
}
}
Real-Time Order Matching
Salah satu fitur paling kompleks: begitu customer bikin order, sistem perlu notifikasi provider terdekat yang available secara real-time. Saya pakai kombinasi Firebase Firestore untuk data real-time dan Firebase Cloud Messaging untuk push notification:
Stream<List<Provider>> getNearbyAvailableProviders(GeoPoint customerLocation, String category) {
return FirebaseFirestore.instance
.collection('providers')
.where('category', isEqualTo: category)
.where('isAvailable', isEqualTo: true)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Provider.fromFirestore(doc))
.where((provider) => _calculateDistance(customerLocation, provider.location) <= 10) // radius 10km
.toList()
);
}
Sistem Rating dan Review
Untuk membangun trust antara customer dan provider (krusial di marketplace on-demand), saya implementasikan sistem rating dua arah — customer menilai provider, dan provider juga bisa menilai customer:
Future<void> submitRating({
required String orderId,
required String fromUserId,
required String toUserId,
required double rating,
String? comment,
}) async {
await FirebaseFirestore.instance.collection('ratings').add({
'orderId': orderId,
'fromUserId': fromUserId,
'toUserId': toUserId,
'rating': rating,
'comment': comment,
'createdAt': FieldValue.serverTimestamp(),
});
// Update rata-rata rating user yang dinilai
await _updateUserAverageRating(toUserId);
}
Local Storage untuk Data Offline
Supaya aplikasi tetap bisa dipakai (setidaknya untuk browsing data yang sudah pernah dimuat) meski koneksi internet tidak stabil, saya cache data penting pakai Hive (local database ringan untuk Flutter):
final box = await Hive.openBox<Order>('cachedOrders');
Future<void> cacheOrders(List<Order> orders) async {
final box = Hive.box<Order>('cachedOrders');
await box.clear();
await box.addAll(orders);
}
List<Order> getCachedOrders() {
final box = Hive.box<Order>('cachedOrders');
return box.values.toList();
}
Push Notification untuk Update Status Order
Future<void> sendOrderNotification(String fcmToken, String title, String body) async {
await FirebaseMessaging.instance.send(
RemoteMessage(
token: fcmToken,
notification: RemoteNotification(title: title, body: body),
data: {'type': 'order_update'},
),
);
}
Tantangan yang Saya Hadapi
- Verifikasi provider — perlu alur onboarding yang cukup ketat (upload KTP, sertifikasi kalau ada) supaya kualitas provider terjaga, ini butuh admin panel terpisah untuk review manual
- Handling lokasi real-time yang akurat tapi tetap hemat baterai — GPS tracking terus-menerus itu boros battery, jadi saya implementasikan update lokasi berkala, bukan continuous streaming
- Payment flow — integrasi payment gateway lokal yang mendukung berbagai metode pembayaran umum di Indonesia
- State synchronization antar multiple screen yang perlu tahu status order yang sama secara real-time
Pelajaran dari Membangun Aplikasi Multi-Role
Beda dari ARES yang berbasis web dengan role-based access lewat Row Level Security, di Flutter mobile app pendekatan role-based UI-nya berbeda — perlu desain navigasi dan screen yang benar-benar terpisah per role dari awal, karena UX customer dan provider itu sangat berbeda kebutuhannya, bukan sekadar toggle permission seperti di web dashboard.
Penutup
Membangun marketplace app kayak JasaKu ngajarin saya banyak hal soal state management kompleks, real-time data sync, dan desain UX multi-role — tantangan yang beda karakter dibanding proyek web SaaS yang biasa saya kerjakan.
Kalau kamu butuh bantuan membangun aplikasi mobile dengan Flutter — marketplace, on-demand service, atau kebutuhan lainnya — saya buka jasa untuk itu. Cek portofolio saya di april-portfolio-pearl.vercel.app atau hubungi lewat halaman Contact.
Ada pertanyaan soal Flutter, state management, atau arsitektur marketplace app? Tulis di komentar.

Tidak ada komentar:
Posting Komentar