Consumer / Collectibles

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.

The Problem

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.

The Build

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.

Features

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.

Architecture

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.
By the Numbers

Verifiable Facts

Dec 2020
First commit to the main repository
Jul 2021
Most recent commit (July 13)
41
Commits, 15 of them by Simon
~20
Screens in the app's main source folder

Counted from the private source repository on October 13, 2026. This page makes no claims about downloads, store releases or revenue.

Lessons

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.

Technologies Used
Flutter•Dart•Firebase ML Vision•Firestore•sembast•MobX•AdMob
Timeline
December 2020 to July 2021

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

SaaS / Business software

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.

Read Case Study →
Consumer / Music

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.

Read Case Study →
AI / Image processing

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.

Read Case Study →
Automotive / Security hardware

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.

Read Case Study →
Landscaping / Field sales

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.

Read Case Study →
AI integration / Open source

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.

Read Case Study →