Mobile App for Classifieds Board
A classifieds board is a highly competitive niche. Avito, OLX, Kufar set the UX and speed benchmark. User leaves if posting an ad takes more than 2-3 minutes or photos load one by one. Technically, key things here are fast search, map search, built-in messenger, and reliable photo upload.
Listing Publication: Minimum Friction
Ad form — category → fill fields → photos → price → publish. Fields depend on category (cars — VIN, mileage, year; real estate — area, floor, deal type). Dynamic form: on category change, fields redraw. JSON Schema from server → form generation on client (avoids field hardcode in code).
Photo upload — biggest bottleneck. User wants 10 photos. Sequential upload — too slow. Parallel — overwhelms mobile network. Optimal: 3 parallel uploads via URLSession background session (iOS) or WorkManager with ListenableFuture (Android). Progress bar for each photo individually.
Compression before upload: UIImage.jpegData(compressionQuality: 0.8) or Bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream). iPhone 15 Pro photos — 8-15 MB raw. After compression — 1-2 MB. Sufficient for classifieds, saves traffic.
Determining Listing Geolocation
Location — either current coordinates, or select on map, or address input with geocoding. For selling items usually district/city without exact address sufficient — safety for seller. Exact coordinates needed for real estate and cars.
Search and Filtering
Full-text search — Elasticsearch or Typesense on backend. Client sends query, 300ms debounce on input field. Search with morphology (Russian language — "машина" finds "машины", "машиной") — via Elasticsearch russian analyzer or Typesense Russian stemmer.
Price filters — range slider. RangeSlider in Material 3 (Android) / custom GeometryReader-based range slider (SwiftUI or RangeSeekSlider library). Debounce values before request.
Map search — user moves map, listings update by visible area. onCameraIdle (Google Maps) / onMapIdle (Mapbox) → request with viewport bbox. Markers on map, tap — listing card.
For real estate, clustering important: 50 listings in one building. Cluster shows count, on zoom-in expands to separate markers or list.
Messenger
Chat between seller and buyer inside app — without exchanging phone numbers. Firebase Realtime Database or Supabase Realtime — fast way to launch real-time chat. For serious scale — own WebSocket server or Stream Chat SDK.
Message structure: { id, conversation_id, sender_id, text, image_url, timestamp, read_at }. read_at for read status. Push on new message — FCM/APNs data push with conversation_id in payload for deep link to specific chat.
Photos in chat — user sends photo. Compress to 800-1200px, upload to S3/Cloudflare R2, message contains URL. On display — lazy load with progressive placeholder.
Anti-spam: message rate limiting (server-side), user blocking.
Listing Moderation
Client-side: warning when phone/email entered in listing text (bypass contacts via platform). "Report" button on each listing — popup with reason, server submission.
Auto-moderation photos: Google Cloud Vision API SafeSearch — explicit content check. Integrates in upload pipeline on server, client gets listing status (pending_moderation / approved / rejected).
Monetization and Promotion
"Bump listing", "VIP status", "highlight" — classic paid options. In-app purchase via StoreKit 2 / Google Play Billing or one-time payment via Stripe.
Push campaigns: notification to owner on favorite add, on price drop of favorited listing by another user.
Stack: Flutter (dev speed important for marketplace), Elasticsearch/Typesense for search, Firebase/Supabase or custom WebSocket for chat, Cloudflare R2 / S3 for media, Google Maps SDK / Mapbox for map.
Phases: category structure and data schema → publication → search and filtering → map → chat → moderation → monetization → testing → release.
Timeline: 14 to 24 weeks. Cost calculated individually.







