DG Card: scan a trading card and match it on the device
A Flutter app for trading card players. Point the camera at a card, on-device text recognition reads it, and the app matches it against a synced card database. From there you track a collection, build decks and trade with other players.
Our role: Our own studio product (DziakStudio was Simon Dziak's earlier studio name), co-built with contractors. Simon made 15 of the 41 commits in the repository; the other 26 came from two other developers.
What DG Card Digital Collection Needed to Solve
Card collectors carry hundreds of cards, and adding each one by hand is slow. The idea was to scan the card instead. The app also had to work with a card database that changes as new sets come out, without charging a Firestore read for every card on every launch, and it needed a way for players to find each other and agree on trades.
How We Built It
The camera feeds each frame to Firebase ML Vision text recognition, which runs on the device. Each recognized line is compared with the card ids in a local database, and a match opens the card page. The card list lives in Firestore. A small version document tells the app when the list changed, and only then does it clear and re-download the cards into a local sembast store. Collections, decks, a trading feed and one-to-one chat sit on Firestore and Firebase Auth.
What the Product Does
Card scanner
A live camera view reads text on the card and opens the matching card page. A type-the-number dialog is the manual fallback.
Collection and decks
Add cards to a collection, create decks from it, and open any card for its details.
Trading feed
Players post cards they want to trade, browse other posts and manage their own.
Chat
Conversations between traders, stored in Firestore.
Profanity filter
The card name in a trade post is checked with a profanity filter before the post is saved.
Ads and purchases
AdMob banner, interstitial and rewarded ad units are set up for both platforms. An in-app purchase service and repository were started, but the service is commented out in the last version of the code.
The Stack, Layer by Layer
- Client app
- Flutter and Dart with MobX for state, get_it for dependency injection and streams from rxdart. About 20 screens in the main folder, plus an unused folder of earlier screens.
- Card database
- Firestore holds the cards and a version number. The app compares that number with one saved in shared preferences. If they differ, it deletes the local copy and downloads the cards again into sembast, so scanning never waits on the network.
- Recognition
- firebase_ml_vision text recognition runs on the device. Each recognized line is compared as a string with each card id.
- Social data
- Firestore collections for trade posts and conversations, and Firebase Storage for card images.
- Monetization
- native_admob_flutter for ads. in_app_purchase and flutter_inapp_purchase are in the dependency list.
Verifiable Facts
Counted from the private source repository on October 13, 2026. This page makes no claims about downloads, store releases or revenue.
What We Learned Shipping It
Sync a catalog once, then read it locally
Re-reading the whole card list from Firestore on every launch costs money and time. A version number plus a local sembast copy makes scanning instant. The code comments say the point was to decrease Firestore cost.
Exact string match is brittle
Matching a whole recognized line to a card id keeps the scanner fast and free of false positives, and the type-the-number dialog covers misses. Glare or a rotated card can defeat it, so a fuzzy match or an id-pattern check is the natural next step.
Three developers, one codebase
Simon and two contractors shipped 41 commits in seven months. The repository still carries a NOT_IN_USE folder of earlier screens, and we would archive dead code sooner and settle on one state-management style from the first sprint.
Ship billing complete or leave it out
Ads are live in the code. The in-app purchase service is parked and commented out, and we would remove it entirely rather than ship it half-wired.
Planning Something Similar?
We build Flutter and Firebase apps for startups and small businesses. Get a ballpark with our app cost calculator, see Flutter development, or tell us about your project.
More Case Studies
Workspace369: a Flutter and Firebase SaaS for client work
An all-in-one workspace for freelancers and small service businesses: CRM, proposals, invoicing and payments, scheduling, a shared email/SMS/voice inbox, accounting and AI, in one Flutter app on iOS and the web.
3693: a private music app in Flutter and Firebase
A private music app built with Flutter: search, a now-playing screen with lyrics, a queue, playlists, liked songs, a cloud library, listening stats and light and dark themes, on a typed Firebase backend.
Deep Dream: a Flutter app and a PyTorch queue behind it
A Flutter app sends a photo to a Python API. A Redis queue hands the job to a PyTorch worker that runs DeepDream on a convolutional neural network, and the dreamed image comes back to save to the gallery.
Bull Horn GPS Alarm: one-tap SMS commands for an alarm
A Flutter app that works as a remote control for GPS vehicle and asset alarms. Each alarm is saved once with its phone number and password, and every command after that is one tap.
Artificial Grass Masters: a field estimator and job sign-off app
A Flutter app for an artificial-turf installer. A rep measures a yard on a map, prices the grass, delivery and dumpster on the spot, and closes the job with photos, a customer signature and a rating. The company gets a text message when a new rating comes in.
saas-mcp-connector: a safe MCP server for a SaaS API
An MCP server that lets Claude Desktop, Claude Code and other MCP clients use a SaaS product's API safely. Every call is scoped to one user's workspace, writes need explicit confirmation, and the HTTP transport is rate limited.