Skip to main content

Flutter and AI: how I revolutionized my apps without rewriting them from scratch

·970 words·5 mins
Andrea Luciano
Author
Andrea Luciano
Founder of Luciosoft, specialized in native mobile development.

It all started with a complaint
#

Let me tell you something. About a year ago I was scrolling through the reviews of Send to Kindle — my app for sending documents to Kindle — and I stumbled upon a review that said something like: “The app works but the converted PDF is garbage, completely unreadable.” One star, obviously.

Now, PDF conversion has always been a pain. Anyone who works with documents knows: a PDF can contain anything. Text, images, tables, insane layouts. And converting it into a readable format for Kindle without losing formatting is a nightmare. For years I used Calibre on the server side to do the heavy lifting, and it worked… sort of.

But that review got me thinking. Maybe it’s time to level up.

The epiphany: AI isn’t just for chatbots
#

Let’s be honest: when people hear “artificial intelligence” they immediately think ChatGPT, chatbots, those things that write your emails. But AI is so much more, especially for mobile app developers.

I figured this out while working on Send to Police, my app for submitting guest registration forms to Italian police. I had already integrated Google MLKit for reading identity documents and Gemini Flash as a fallback for the most desperate cases. And it worked beautifully. So I thought: if AI can read a crumpled 1987 paper ID card with a faded photo, why can’t it help me with PDFs?

What I actually did
#

I started integrating AI at strategic points in my Flutter apps, without rewriting everything from scratch. This is the key point: you don’t need to throw away your existing code. AI plugs in as an additional layer.

1. Smart document recognition
#

In Send to Police I built a cascading system:

  • First attempt: MLKit on-device, fast and private. Works great for passports and electronic ID cards.
  • Second attempt: proprietary algorithm for old Italian paper ID cards (the ones even your grandmother can’t read).
  • Third attempt: Gemini Flash via API, only with user consent.

The beauty of Flutter is that managing this cascade is natural. A well-structured try-catch, some async/await, and you’re done. The user doesn’t notice anything: they take a photo and the data appears.

2. Smarter PDF conversion
#

In Send to Kindle I added a pre-conversion analysis layer. Before sending the PDF to the Calibre container, the app now analyzes the document to determine if it’s a scanned PDF (basically an image), a PDF with real text, or a mix of both. This analysis determines what type of conversion to apply.

For scanned PDFs I integrated OCR with AI support, which recognizes text in images. The result? Conversions that were previously unreadable now come out clean. That one-star review might be worth at least three stars now. Maybe.

3. Firebase as the glue
#

One thing I’ve learned over the years is that Firebase is the indie developer’s best friend. In both apps I use:

  • Firebase Remote Config to manage feature flags without releasing updates
  • Cloud Functions for lightweight backend
  • Firebase Storage for file management
  • Pub/Sub to communicate with conversion containers

The integration with Flutter is flawless thanks to FlutterFire plugins. If you haven’t checked them out yet, I highly recommend giving them a try.

If you’re curious about how I use these tools in my projects, stop by luciosoft.it.

The problems nobody tells you about
#

But it’s not all sunshine and rainbows. Let me share some mishaps:

Memory explosion — When I deployed the PDF conversion container on Cloud Run, large files crashed everything. I had to go from 2GB to 4GB of RAM, and for really huge files you need 8GB. At one point I thought: I’m running a nuclear power plant just to convert a PDF. But it works.

The -1017 bug — Firebase Storage has a mysterious error, code -1017, that pops up when you upload files downloaded from Google Drive. I spent two days debugging before realizing the issue was in how iOS handles temporary files. The solution? Use putData instead of putFile. Two lines of code, two days of work. Classic.

Grandpa’s ID cards — My recognition algorithm for old paper IDs works well in 90% of cases. But that remaining 10%… people with documents folded in four, kept in their wallet for twenty years, with a photo that looks like an impressionist painting. For those, there’s Gemini Flash, which sometimes manages to extract data even from those desperate situations.

Tips for those who want to get started
#

If you develop Flutter apps and want to integrate AI, here’s what I suggest from my experience:

  1. Start with the problem, not the technology. Don’t add AI because it’s trendy. Add it where it solves a real user problem.

  2. Use a cascading approach. AI isn’t infallible. Having a fallback (or two, or three) is essential. On-device first, cloud second.

  3. Privacy first. Especially with sensitive data like identity documents. Data should travel as little as possible.

  4. Firebase Remote Config is your friend. You can toggle AI features on and off without releasing an update. Trust me, you’ll need this.

  5. Test with real files. Tests with perfect files always pass. But then a user shows up with a 50MB PDF generated by a 2003 scanner and everything explodes.

What’s next?
#

I’m working on new integrations. The idea is to use lighter AI models directly on-device for certain tasks, without going through the cloud. Flutter with its plugins and the growing community makes all of this possible.

If you want to try my apps:

And if you feel like it, stop by luciosoft.it to see what else I’m up to. Spoiler: more apps, more experiments, and probably more bugs to fix.