🧠 The Headaches, the Heartache, and the Obsession: The Raw Reality of Building Our Apps
Building this app nearly broke me. From real-world database synchronization conflicts that threw 'unauthenticated' loops, to aggressive auto-cropping cameras that cut off card edges, and production hotfixes pushed at midnight, here is the raw, unfiltered story of what it took to perfect this code.
Let's be completely honest for a moment. Building an app is not like tuning an air handler. When you're servicing a furnace, you diagnose the limit switch, you swap it out, and the system runs. It's logical. It's direct.
Building software, on the other hand, is a bizarre exercise in pulling your own hair out. For the past year, I have poured every single ounce of my free time, energy, and sanity into perfecting our applications. I did it because I care deeply about building high-quality, practical tools for people who need them. But getting to this point? It has been a road paved with extreme headaches, sleep deprivation, and moments where I was ready to throw my computer off a three-story roof and delete the entire repository.
The 'Fix One Thing, Break Another' Nightmare
In the software world, they call it 'regression.' When you're managing a complex app that runs locally on SQLite but syncs in real-time to a Firebase cloud database, the code behaves like a house of cards built on a washing machine during a spin cycle.
For example, we ran into a loop during a local smart sync where 22 backup images were marked as 'orphans.' Tapping restore did nothing, and clicking delete appeared to clear them, only for the same 22 images to instantly reappear on the next sync. Worse, clicking the 'Fix Missing Images' utility threw a frustrating 'unauthenticated' error. It turned out to be a database transaction timing conflict between AsyncStorage and Firebase auth states. Tracing and resolving that issue took three sleepless nights of pure frustration. You fix one leak only to have two more spring up elsewhere.
The Camera Cropping and Math Snapping Battle
Then there was the camera cropping nightmare. Tapping 'Identify' or scanning nameplates should be seamless. But our auto-cropper was incredibly aggressive, cutting off the literal edges of scanned cards or data plates. We wanted it to crop slightly *outside* the boundaries to ensure the entire item was captured.
However, when we tried to adjust it manually, a scaling bug made the whole crop box shrink unpredictably and snap the image to the top-left corner instead of saving the selected area. Mapping camera aspect ratios to screen coordinates without stretching or snapping took dozens of trial-and-error mathematical changes.
All Hands on Deck: The Live-Production Panic
It's one thing when a bug happens on your computer during testing. It is an entirely different, soul-crushing terror when it happens live. We pushed an update that accidentally broke the offline database query on certain older Android devices, causing the app to force-close immediately on launch.
Within minutes of the update going live, my inbox started lighting up. Technicians in the field and collectors trying to scan their items couldn't open the app at all. In those moments, your stomach drops. It is an absolute, all-hands-on-deck, red-alert nightmare. You drop everything. You skip meals. You ignore the world. You sit at your desk in a cold sweat, desperately tracking down the state initialization bug, coding a hotfix, and pushing an OTA (over-the-air) architecture patch to get users back up and running. The pressure is immense, the stakes are real, and the exhaustion that follows is bone-deep.
Crushing AI Hallucinations and Login Bugs
AI is powerful, but it does not always get it right on the first pass. Early versions of our AI nameplate scanner would occasionally confuse a model number suffix for a separate field, or pull a filter size off a nearby sticker that had nothing to do with the unit being scanned. Every one of those failure modes had to be hunted down, reproduced, and fixed with tighter prompt engineering and strict field validation rules.
We also fought a persistent bug where the app would log the user out every single time they closed it. Having to re-enter credentials on every launch is a dealbreaker for a field tech who opens the app a dozen times a day. We had to implement AsyncStorage persistence listeners to ensure sessions safely survived restarts — something that sounds simple and took a week to get right across both iOS and Android.
Why I Refused to Give Up
There were at least a dozen times during this journey where I was ready to quit. I was tired of the late nights, the stress, and staring at lines of TypeScript that looked like hieroglyphics. But every time I almost gave up, I thought about the end goal.
I wanted to build something that was actually *useful*. I didn't want to create some bloated, expensive enterprise software. I wanted a tool that was fast, convenient, and incredibly intuitive—something you can rely on without constant bugs. And because I care so much, I made the core app completely free. It can't hurt to give it a try.
My hope is that all of my headaches, the live-production panics, the crop-math issues, and the sync battles will make your job just a little bit easier and bring more convenience to your home.
Jonathan Curtis
HVAC Technician & Founder · Equipment Tracker Pro
Jonathan Curtis is an HVAC technician and the founder of Equipment Tracker Pro. He built the app to solve real problems he encountered in the field — including the daily frustration of unreadable nameplates on aging rooftop equipment.
Try Equipment Tracker Pro Free
Core equipment tracking is free forever. Pro features include AI nameplate scanning, condition assessment, invoice scanning, cloud sync, and more.