Taking Flutter seriously: from idea to Play Store and Wasm web
What I learned shipping PokeData for real — Android, Firebase, Cloudflare Pages/Workers, CI/CD, and the ugly tradeoffs tutorials skip.
Side projects reveal engineering too. PokeData started as a Pokédex, but the challenge I cared about was not “call a Pokémon API”: it was closing the loop on a mobile-first product with backend, auth, persistence, store, and production web.
Open source on GitHub, live at pokedata.kaique.site, and on the Play Store. Below is what actually hurt — and what I would repeat.
One codebase, two hostile surfaces
Flutter shines in multiplatform slides. In practice Android and Web disagree on auth, security headers, deep links, and Wasm cost. I wanted an app that felt right under a thumb and still survived in the browser without being an afterthought.
Riverpod for state, Firebase Auth + Firestore for identity and favorites, guest mode to cut friction. Google Sign-In on mobile; email/password on web — because multi-thread Wasm with COOP/COEP does not play nice with Firebase’s Google Auth helpers. That is not an excuse: it is a documented, conscious tradeoff.
Production is not flutter run
Secrets out of git (dart_defines, CI secrets). Release-signed App Bundle. Custom domain on Cloudflare Pages with SPA redirects and headers aimed at SharedArrayBuffer. A pipeline that runs analyze and tests on every push, production deploy on master, and per-PR previews.
Each item is boring. Together they are the difference between “I have a Flutter repo on GitHub” and “I operate an app”.
Guess the Pokémon — and free tier as a design constraint
A Pokédex alone is still a “reference app”. Guess the Pokémon forced a second product in the same codebase: local mode with a bundled catalog, and competitive mode via Cloudflare Worker + D1, Firebase tokens on mutations, leaderboards, and rate limits.
The Worker does not call PokéAPI at request time — the catalog is checked into the repo. A usage monitor watches Workers/D1 daily ceilings. $0 infra is not a slogan: it shapes sessions, abuse caps, and the fact that competitive mode is optional if the API URL is unset.
Why this belongs in my professional story
At work I live in Java/Spring, Vue, and Azure on industrial systems. With PokeData I proved the other arm: hybrid mobile, Firebase/GCP, Cloudflare (Pages + Workers/D1), and release discipline without a platform team holding my hand.
A recruiter who only reads the job title sees “industrial full-stack”. Someone who opens PokeData sees a person who also ships end-to-end when the product is mine — including the unglamorous parts.