Skip to content

MSc

Peer Store

An Android marketplace built on Firebase with on-device object detection and, in hindsight, a good example of how an async API returns a value that is always zero.

Nov 2022Machine learning

An Android marketplace for an MSc mobile-development course: register, post an item with a photo and a price, browse what other people have posted, and leave messages under a listing. Ten activities in Kotlin over Firebase auth, Firestore and Storage.

Context
MSc mobile development, Sapienza
Features
Listings · image labels · public message threads
Stack
Kotlin · Firebase · ML Kit object detection
Repository
VincenzoImp/peer-store
VincenzoImp/peer-storeAndroid marketplace with Firebase backend and on-device object detection.Kotlin

What it was

The interesting piece is that the object detection runs on the device. ML Kit’s bundled base model labels the uploaded photo and the labels are stored alongside the listing: no network call, no API key, no image leaving the phone. It does not fill in the form; the seller still types the title, description and price, and the labels appear as their own field on the listing.

Messages under a listing are a public thread rather than a private conversation, kept as an array on the post document.

What I took from it

Two bugs in this repository taught me more than the app did.

The first is a shape I now recognise instantly. Location is read like this: declare a variable, ask for the last known location, assign it inside the success callback, return the variable. The callback cannot have run by the time the function returns, so every listing was written with a latitude and longitude of exactly zero, and every distance in the browse screen rendered as zero. Nothing threw. The code reads correctly if you do not know that the call is asynchronous.

The second is the message thread: read the array, append, write the whole array back. Two people posting at the same moment means one message disappears, and no error is raised anywhere. The fix – an atomic array append – is one method call, and knowing it exists is the entire difference.

Neither is a subtle race in production code. They are both the default mistake for the API in question, which is exactly why they are worth remembering.