↑
← Blogs
Apr 23, 2026•

How I Built And Shipped Physdaily Solo Flutter Firebase And Ai Deep Dive

ullas kunder
Ullas Kunder

Designer & Developer

Table of Contents
  1. 1.How I Built and Shipped PhysDaily Solo: Flutter, Firebase, and AI Deep Dive
  2. 2.Who Is This For?
  3. 3.The Product: PhysDaily
  4. 4.1. Why This Stack? The Speed-to-Market Argument
  5. 5.Flutter: One Codebase, Zero Compromise on Feel
  6. 6.Firebase: "No-Ops" Backend
  7. 7.2. The Architecture: Three Separate Repositories, One Product
  8. 8.3. The CMS: Content-as-Code with an AI Layer
  9. 9.The Problem with Traditional CMS
  10. 10.How the Pipeline Works
  11. 11.JSON Growth Management
  12. 12.The Roadmap: PDF-to-Question Pipeline
  13. 13.4. Engineering Decisions Inside the App
  14. 14.State Management: Right-Sized, Not Over-Engineered
  15. 15.Local Persistence: Offline-First by Default
  16. 16.5. Keeping It Lean: Asset and Performance Decisions
  17. 17.6. The Brand: Designed with Intent
  18. 18.Getting Through the 14-Day Closed Beta
  19. 19.7. What's Coming: The Engagement Roadmap
  20. 20.Notification Layer: Curiosity-Driven Re-engagement
  21. 21.Reward System: Dopamine, Not Addiction
  22. 22.Social Layer: Peer-Triggered Challenges
  23. 23.8. Scaling to 100k Users: What Would Break First
  24. 24.Reflection
  25. 25.Try It

How I Built and Shipped PhysDaily Solo: Flutter, Firebase, and AI Deep Dive

TL;DR: I built, branded, and shipped a cross-platform physics challenge app — complete with a custom AI-powered CMS, Firebase backend, and a 14-day closed beta — as a solo engineer. Here's every architectural decision, every trade-off, and what comes next.

hero banner / PhysDaily product page

Who Is This For?

If you're a developer curious about shipping a full-stack mobile product solo, this post is for you. No team. No startup runway. Just deliberate engineering decisions, the right tools, and a bias for shipping. By the end of this, you'll walk away with a clear picture of how to architect a Flutter + Firebase app, build a lightweight AI-powered CMS, and launch on Google Play — from idea to production.

The Product: PhysDaily

PhysDaily is a daily physics challenge app inspired by the classic "Physics Bowl" format — think Wordle, but for physics students, competitive exam aspirants, and anyone who wants to keep their analytical thinking sharp in the age of instant AI answers.

Core loop: Open the app → solve one carefully crafted daily problem → build your streak → come back tomorrow.

It's live. It's reviewed. It's on Google Play.

  • Stack: Flutter · Firebase Firestore · Node.js · Next.js
  • Platform: Android (iOS coming)
  • Brand: iProfile Labs

This image will go here — Google Play listing screenshot

1. Why This Stack? The Speed-to-Market Argument

The decision to ship fast without sacrificing quality starts at the stack level.

Flutter: One Codebase, Zero Compromise on Feel

A "Wordle-style" daily game lives and dies by its tactile feel — the satisfying flip of a card, the shake of a wrong answer, the glow of a correct one. Native Android would have been fast to write but slow to port. React Native would have required bridging native modules for complex animations.

Flutter gave me both: a single codebase and a high-performance rendering engine that runs completely independently of the platform's native UI widgets. Using flutter_animate, I was able to build smooth micro-animations flips, shakes, glows in a fraction of the time it would have taken in a dual-codebase native setup.

Decision: Flutter over React Native, not because React Native is bad, but because Flutter's rendering model gave me the animation fidelity I needed without a performance tax.

Firebase: "No-Ops" Backend

I'm one engineer. I don't want to manage a database server, write a REST API, handle auth for a content pipeline, and build a mobile app simultaneously. Firebase's Cloud Firestore eliminated the first two entirely.

The critical win was real-time push: the moment I deploy a new puzzle from the CMS, every user's app receives it globally no app update, no cache-busting, no version bump. For a daily challenge format, that's the infrastructure property that matters most.

[this image will go here architecture overview diagram: Flutter App ↔ Firestore ↔ CMS]

2. The Architecture: Three Separate Repositories, One Product

What most solo projects get wrong is monolith thinking. I made an early call to separate concerns across three distinct codebases:

Repository Tech Purpose
fiz-day-lee Flutter / Dart The mobile app users install
fiz-day-lee-cms Node.js / Next.js The content pipeline (CMS)
iprofile-dev Web Brand, portfolio, and landing page

This separation paid off immediately. Updating the CMS doesn't touch the app. Rebuilding the landing page doesn't break the content pipeline. Each piece is independently deployable and testable.

3. The CMS: Content-as-Code with an AI Layer

This is the part I'm most proud of architecturally and the part nobody sees.

The Problem with Traditional CMS

Building a full web-based admin panel (with auth, a rich text editor, and a deployment pipeline) for a solo V1 is over-engineering. I needed to publish a new physics question every day. A puzzles.json file and two scripts turned out to be the right abstraction.

How the Pipeline Works

Step 1 AI Question Generation

Instead of writing questions manually, I built a script that calls an LLM with structured parameters:

Topic: Rotational Motion
Difficulty: Medium
Format: Multiple-choice, 4 options

The model generates a question, four options, the correct answer, and a brief explanation and writes it directly into puzzles.json. One command. Done.

Step 2 The "Rule-Flip" Deployment

Pushing the updated JSON to Firestore without a complex admin auth system required a pragmatic hack. I wrote updatedb.js, a Node.js script that:

  1. Temporarily opens Firestore Security Rules to allow write: if true
  2. Deploys the updated rules via firebase-tools
  3. Syncs the JSON to Firestore
  4. Immediately reverts the rules to allow write: if false
// updatedb.js simplified
await deployRules({ write: 'if true' });
await syncJsonToFirestore('./puzzles.json');
await deployRules({ write: 'if false' });
console.log('✅ Puzzles synced. Rules reverted.');

My local Firebase credentials act as the "key." The window of vulnerability is seconds. This is a conscious V1 trade-off and it worked perfectly.

[this image will go here CMS pipeline diagram: AI Script → puzzles.json → updatedb.js → Firestore → App]

JSON Growth Management

One practical concern: puzzles.json grows with every question added. My current thinking is to implement a rolling window once the archive hits a threshold (say, 90 questions), the oldest entries are pruned from the JSON before the next sync. Firestore holds the canonical history; the local file is just the staging ground.

The Roadmap: PDF-to-Question Pipeline

The longer-term vision is to connect a small, locally-run LLM to a physics textbook PDF. The model reads a chapter, extracts key concepts, and generates a week's worth of questions fully automated, zero manual authoring. A weekly cron job handles the sync. This brings the content engine closer to self-sustaining.

4. Engineering Decisions Inside the App

State Management: Right-Sized, Not Over-Engineered

In Flutter, you have options: Riverpod, Bloc, Provider, ChangeNotifier. The community debates this constantly. My answer: choose based on the actual complexity of the app, not on what impresses in interviews.

PhysDaily is, at its core, a single-activity game loop. One puzzle. One session. One streak counter. A global GameManager singleton using ChangeNotifier was the correct level of abstraction.

class GameManager extends ChangeNotifier {
  static final GameManager _instance = GameManager._internal();
  factory GameManager() => _instance;
 
  int _streak = 0;
  bool get hasPlayedToday => _lastSessionId == _todaySessionId;
 
  Future<void> completePuzzle() async {
    if (hasPlayedToday) return;
    _streak += 1;
    await _saveToLocal();
    notifyListeners();
  }
}

It manages the current puzzle, calculates the 7 PM unlock logic (a specific design decision to create a daily "event" feel), and notifies the UI on state changes. No additional dependencies. No boilerplate overhead.

Lesson: Riverpod is excellent. It was also complete overkill here. Choosing the simplest adequate tool is a senior engineering call.

Local Persistence: Offline-First by Default

User progress streak count, last_played_session_id lives in shared_preferences. This means:

  • The app works offline (streak display, previous results)
  • Progress survives app kills and reboots
  • The user's psychological investment (their streak) is never at risk

This "sticky" design is intentional. If a user feels their 15-day streak is permanent and reliable, they're more likely to protect it which drives retention.

banner

5. Keeping It Lean: Asset and Performance Decisions

Mobile users notice app size. I kept PhysDaily under 10MB through two deliberate choices:

Dynamic Content over Bundled Assets

Physics problems are text and LaTeX formulas not images. By fetching puzzle content as raw strings from Firestore at runtime, I bundle zero puzzle-specific assets in the APK. The app is a shell; the content is the service.

Vector-First UI

Every icon comes from fluentui_system_icons. Every UI element is drawn in code not rasterized as PNGs. The result is pixel-perfect rendering on every screen density, with no asset inflation.

Security: Firebase AppCheck

Even with the Pseudo-CMS approach, I locked the frontend using Firebase AppCheck. Only the legitimate, signed Flutter app can query Firestore. Bots and scrapers trying to harvest daily answers hit a wall.

6. The Brand: Designed with Intent

The visual identity the app icon, Play Store screenshots, landing page was crafted using Canva AI and Gemini, then refined by hand. The brand home is iProfile Labs, a portfolio that positions PhysDaily alongside other focused tools I've shipped: Darvin IDE, SwidoMark, and Turai Blog.

The philosophy: Simple software, thoughtfully crafted.

iProfile Labs website screenshot / PhysDaily product page

Getting Through the 14-Day Closed Beta

Google Play's internal testing requires a minimum of 12 testers active for 14 consecutive days before an app can proceed to production review. As a solo developer with no existing user base, this is a real barrier.

My solution: I used my LinkedIn network and iProfile.dev portfolio to drive interest. I shared a Google Form framed not as "please test my app" but as "be first to try a physics challenge app before launch." The positioning mattered. I hit 12 testers, completed the 14-day window, and cleared production review.

Lesson: Distribution is an engineering problem. Solve it with the same intentionality as your code.

7. What's Coming: The Engagement Roadmap

Shipping V1 is the beginning. Here's the product thinking for what comes next, grounded in behavioral design principles.

Notification Layer: Curiosity-Driven Re-engagement

The risk with a daily habit app is that users simply forget. The plan is a notification system built around curiosity triggers, not pressure:

"Hey do you know why objects in free fall are actually weightless? 🤔"

The notification doesn't say "You haven't opened the app." It poses a question that makes you want to know the answer. That's the psychological hook and it respects the user's intelligence.

The implementation would use scheduled local notifications or Firebase Cloud Messaging, with a configurable "quiet window" the user sets themselves.

Reward System: Dopamine, Not Addiction

After a correct answer, the plan is to surface a small, satisfying reward a growing tree built from seeds, or a "gotcha sticker" mechanic similar to collectible systems in games like Duolingo.

The key design constraint: the reward should feel good without engineering compulsive behavior. There's no streak-penalty. No loss aversion. The tree grows; it never dies. The goal is to make the user feel good about engaging, not anxious about disengaging.

reward / tree growth concept sketch or mockup

Social Layer: Peer-Triggered Challenges

One of the strongest engagement mechanics in daily challenge apps is the social proof loop:

"Your connection just answered this question. Try it."

A lightweight "Connections" feature where users can see (anonymously or by name) that someone in their network attempted today's challenge would dramatically increase motivation without requiring a full social graph. This is closer to Strava's "kudos" mechanic than Facebook's feed.

8. Scaling to 100k Users: What Would Break First

V1 was built for shipping. Here's the honest assessment of what would need to change at scale:

1. Move the 7 PM Rule server-side

Currently, the daily unlock logic lives in the Flutter client. At scale, a determined user can change their device clock and unlock future puzzles. A Firebase Cloud Function that validates the session timestamp server-side closes this exploit permanently.

2. Replace the Rule-Flip with Admin SDK + IAM

The Security Rule Flip is a solo-developer power tool. For a team or even for peace of mind at scale migrating the CMS to use the firebase-admin SDK with proper IAM roles eliminates the temporary open-write window entirely.

3. Edge Caching for the Daily Puzzle

The daily puzzle is the same document for every user. At 100k daily active users, that's 100k Firestore reads for a single document. Routing the puzzle fetch through Firebase Hosting with aggressive CDN cache headers would reduce this to near zero database load for the most common read operation.

Reflection

PhysDaily started as a question: Can I build a premium-feeling mobile product, alone, without a backend team, without burning months on infrastructure?

The answer is yes with the right trade-offs. Flutter and Firebase gave me the leverage. The AI-assisted CMS pipeline gave me sustainable content operations. And the discipline to keep each layer of the architecture focused and independent gave me the confidence to ship, iterate, and plan what's next.

This wasn't just an app. It was a complete exercise in product thinking, system design, and distribution compressed into a single solo project.

Try It

📲 Download PhysDaily on Google Play

🌐 Product page iprofile.dev/phys-daily

Have thoughts on the architecture, the CMS pipeline, or the engagement roadmap? I'd love to hear from you — connect with me on LinkedIn or open an issue on GitHub.

← Previous

leetcode 417 pacific atlantic water flow

Next →

graphics template