Development

Firebase Review 2025: The Backend You Ship In a Weekend

SR
Suresh Reddy
February 18, 2025
15 min read
Firestore NoSQL DB Auth Identity Functions Serverless Hosting CDN + SSL Crashlytics Crash Reports Storage Files + CDN One console. One SDK. One bill. That is the pitch.

It was 2 AM on a Thursday and I was staring at a Firestore security rule that was rejecting every single write request, and I could not figure out why. My demo was in seven hours. I had been working on this app for a hackathon -- a real-time collaborative grocery list thing, nothing groundbreaking -- and the authentication tokens were valid, the data structure was correct, and the rule syntax looked fine. I was on my fourth cup of chai and my third Stack Overflow tab when I realized I had spelled "request" as "reqeust" in one of the match patterns. One typo. Two hours of debugging. Welcome to Firebase, the platform that will let you build a complete backend in a weekend and then make you spend half of that weekend fighting with its security rules.

That was three years ago. Since then I have shipped three production apps on Firebase -- a task manager for a small SaaS startup, a social recipe-sharing app that peaked at about 8,000 monthly active users, and a real-time dashboard for a client's IoT sensors. I have been through the highs (deploying a fully functional app in 48 hours) and the lows (a Firestore bill that jumped from thirty-seven dollars to two hundred and eighty dollars in a single month because of a badly structured query). I know where Firebase is magic and where it will bite you. This is that review.

The Prototype Phase: Where Firebase Is Genuinely Magical

When you are building something new and you just want it to WORK, Firebase is unbeatable. I am not using that word loosely. I have tried building prototype backends with Express + PostgreSQL, with Supabase, with AWS Amplify, and with Firebase. Firebase wins every time for speed to first working version.

Here is what my setup looks like when I start a new project. I run firebase init in my terminal. I pick Firestore, Auth, Functions, Hosting, and Storage from the menu. I write maybe 20 lines of security rules. I add the Firebase JS SDK to my React app. And in about an hour, I have: a NoSQL database with real-time listeners, user authentication with Google sign-in AND email/password AND anonymous auth, file uploads to Cloud Storage, serverless functions for backend logic, and a globally distributed CDN hosting my frontend with automatic SSL. All of that. One hour. One Google account. One CLI.

Time to First Working Prototype (My Real Experience) Firebase ~2 hours Supabase ~4 hours Express+PG ~2 days Amplify ~1-2 days

The real-time sync is what sealed the deal for me. When I was building the grocery list app, I added a Firestore snapshot listener and suddenly every connected client was seeing changes instantly -- under 200 milliseconds across devices sitting next to each other on my desk. I did not set up WebSockets. I did not configure a pub/sub system. I did not think about connection pooling or event queues. I wrote onSnapshot() and it just worked. That moment, the first time you see data update across two browser tabs in real time with zero backend code, is the moment Firebase hooks you.

Authentication is similarly effortless. Firebase Auth supports Google, Apple, Facebook, Twitter, GitHub, Microsoft, phone number (SMS), email/password, and anonymous auth out of the box. Setting up Google Sign-In -- which would involve registering OAuth credentials, handling redirect flows, managing token refresh, and dealing with CORS if you built it from scratch -- took me 12 lines of code and about 15 minutes including the Google Cloud Console configuration. Anonymous auth is particularly clever: it assigns a persistent user ID to someone who has not signed up, and when they eventually create an account, you can link the anonymous session to their real account and preserve all their data. I used this for the recipe app to let people save recipes before creating an account, and it noticeably improved conversion.

The Production Phase: Where Things Get Interesting

Moving from prototype to production on Firebase is where you start learning the hard lessons, and I want to be very honest about them because they cost me both time and money.

Firestore's data model is a document database. No JOINs. No foreign keys. No complex aggregations without writing your own Cloud Functions. If you come from a SQL background -- and most backend developers do -- your first instinct will be to model your data relationally. You will create a "users" collection and a "posts" collection and think "I will just join them when I need a post with user info." WRONG. That is not how Firestore works. You need to denormalize your data, which means storing the user's name and avatar directly on each post document, and then updating all of those copies when the user changes their name. This feels wrong to anyone who learned about database normalization, and it IS a trade-off. But it makes reads incredibly fast because you never need to join anything.

The querying limitations are the thing that will frustrate you most if you have SQL muscle memory. You cannot query across collections without collection group queries (which have their own security rule requirements). You cannot do full-text search at ALL -- you need a third-party service like Algolia or Typesense. You cannot do inequality filters on multiple fields in a single query. You need composite indexes for compound queries, and while Firestore helpfully generates the index creation link in the error message when you need one, the process of discovering which indexes you need feels like trial and error. I spent an entire afternoon during the recipe app project creating composite indexes because my search-by-ingredient-and-cuisine query needed them.

Cloud Functions on the second-generation runtime are significantly better than they used to be. Cold starts were once so bad they were practically a meme in the Firebase community -- your function would take 5-10 seconds to wake up, making it useless for user-facing requests. The V2 runtime, built on Cloud Run, has cut that to under 800 milliseconds for Node.js functions in my testing, and warm invocations complete in 50-100 milliseconds. V2 also supports concurrency, meaning a single function instance can handle multiple simultaneous requests instead of spawning a new instance for each one. This was a huge pain point that Google actually fixed, and I respect that.

But. Cloud Functions debugging is still painful. The Firebase Emulator Suite helps -- you can run Firestore, Auth, Functions, and Hosting locally and test everything without deploying. I use it constantly. But when a deployed function behaves differently from the local emulator (and it happens more than you would expect), you are reduced to adding console.log statements and reading Cloud Logging, which is slow and clunky. There is no real remote debugger. No breakpoints. Just logs. In 2025, for a Google product, that feels behind.

Firebase Joy Curve (Based on My 3 Projects) Happiness Day 1: WOW Week 1: Ship it! Month 1: The bill... Month 3: OK, I get it now

Hosting, Storage, and the Stuff Nobody Talks About

Firebase Hosting is quietly great. You run firebase deploy and your site goes to a global CDN with automatic SSL, custom domain support, and atomic deploys (meaning if a deploy fails, nothing changes -- you do not get a half-deployed site). Preview channels let you deploy feature branches to temporary URLs, which is perfect for showing in-progress work to clients. I deployed a Next.js app with server-side rendering handled by Cloud Functions, and the setup took about 20 minutes with time-to-first-byte consistently under 200 milliseconds from test locations in India, the US, and Europe. For a serverless hosting solution, that is genuinely impressive.

Cloud Storage for Firebase is just Google Cloud Storage with a Firebase SDK wrapper that adds client-side security rules. It works well for user-uploaded content -- profile photos, file attachments, media. The security rules integrate with Auth so you can write rules like "users can only upload files to their own folder" without any backend logic. I use the Resize Images extension to automatically generate thumbnails when users upload images, and it was operational in under 10 minutes -- install the extension, choose the sizes, done.

Crashlytics is genuinely the best free crash reporting tool for mobile apps. I say this as someone who has used Sentry, Bugsnag, and Instabug. The crash grouping is intelligent, the stack traces are detailed, the velocity alerts (which ping you when a new crash starts affecting a growing percentage of users) have saved me from embarrassing production issues more than once. It is free. Unlimited. And it is honestly better than most of the paid alternatives. If you are building a mobile app and not using Crashlytics, you are making your life harder for no reason.

Firebase Cloud Messaging (FCM) handles push notifications across iOS, Android, and web at no cost regardless of volume. Setting up targeted notifications based on user segments defined through Analytics is straightforward, and the Notifications Composer in the Console lets non-technical team members send messages with A/B testing without touching code. Remote Config lets me change app behavior without publishing updates -- I use it for feature flags, seasonal content, and emergency kill switches. When we discovered a bug in the recipe app's sharing feature, I toggled a Remote Config flag to hide the share button while we worked on a fix, all without pushing an update through the app stores. That kind of operational flexibility is hard to replicate with traditional deployments.

Supabase vs Firebase: I Have Used Both and Here Is What I Think

Supabase keeps coming up in every Firebase discussion, and for good reason. It positions itself as the "open source Firebase" and it genuinely delivers on that promise in some areas. The fundamental difference is the database: Supabase gives you PostgreSQL. Real PostgreSQL. With JOINs, foreign keys, full-text search, indexes, triggers, stored procedures -- the entire SQL toolkit that Firebase deliberately does not offer.

For my IoT dashboard project, I seriously considered Supabase because the data was naturally relational -- sensors belong to devices, devices belong to locations, readings have timestamps and need aggregation. That is a SQL problem. Firestore would have required denormalization gymnastics that would have made the code ugly and the data model fragile. I ended up choosing Firebase anyway because the real-time sync was more mature and the project had a tight deadline, but if I were starting that project today, I might choose differently. Supabase's real-time capabilities have improved significantly.

Where Firebase still wins: mobile SDKs, Crashlytics, Cloud Messaging, Remote Config, offline persistence on mobile, and the sheer maturity of the platform. Where Supabase wins: data modeling flexibility, SQL queries, open source (no vendor lock-in), self-hosting option, and a more intuitive dashboard for people with SQL experience. If you are building a mobile-first app that needs push notifications and crash reporting, Firebase. If you are building a web app with complex data relationships, Supabase. That is the honest split.

AWS Amplify is the third option I hear about a lot. I tried it for a project once and gave up after two days. The documentation was fragmented across three different docs sites, the CLI kept generating massive configuration files I did not understand, and setting up authentication through Cognito felt like solving a puzzle designed by committee. Amplify is powerful if you are already in the AWS ecosystem and have team members who know AWS services. If you are a small team or solo developer looking for the fastest path to a working product, it is the wrong choice. Firebase or Supabase will get you there in a fraction of the time.

PocketBase deserves a mention too -- it is a single Go binary that gives you a SQLite database, auth, real-time subscriptions, and file storage. You download it, run it, and you have a backend. For personal projects and internal tools, it is beautiful. For production apps that need to scale beyond a single server, it is not the right fit. But it is free, open source, and you own everything. If vendor lock-in keeps you up at night, look at PocketBase.

The Billing Thing -- I Need to Be Honest About This

Firebase's free Spark plan is genuinely generous. You get 1 GB of Firestore storage, 50,000 reads per day, 20,000 writes per day, 10 GB of hosting, 5 GB of Cloud Storage, and unlimited Authentication users. For a side project or an early-stage prototype, this is more than enough. I ran the grocery list app on the Spark plan for four months before it outgrew the limits.

The Blaze plan is pay-as-you-go with the Spark limits as a free quota. This means you only start paying when you exceed the free tier. For many small to medium apps, the monthly cost on Blaze is surprisingly low -- my task manager SaaS with about 500 active users costs around forty-two dollars a month on Blaze. That is cheap for a fully managed backend with auth, database, functions, and hosting.

BUT. And this is a big but. Firestore bills per document read. Every time your app loads a list of 50 items, that is 50 reads. Every time a real-time listener fires because someone updated a document, everyone listening to that collection gets charged a read for each updated document. If you are not careful with your queries -- if you are fetching entire collections instead of paginating, if you are using broad real-time listeners when you could use more targeted ones, if you are not caching heavily on the client -- your bill can spike suddenly and alarmingly.

This happened to me. The recipe app had a "trending recipes" page that queried the top 50 recipes ordered by a popularity score, with a real-time listener that updated live. Every time someone liked a recipe, the popularity score changed, the query re-fired for every connected client, and each client was charged 50 reads. At 8,000 monthly active users with maybe 2,000 daily actives, the reads were accumulating fast. My Firestore bill went from thirty-seven dollars to two hundred and eighty dollars in one month. I panicked. I restructured the query to use pagination (10 at a time instead of 50), replaced the real-time listener with a periodic fetch every 60 seconds, and added client-side caching. The bill dropped to sixty-one dollars the next month. Lesson learned, but it was an expensive lesson.

Firebase now has budget alerts, which is good. Set them up immediately on any Blaze project. There is no spending cap though -- the alerts warn you, but they do not stop the charges. Google Cloud has a billing budget feature that can theoretically cap spending, but it is not integrated into the Firebase Console and requires fiddling with Google Cloud IAM. This is a real problem for developers building side projects who are terrified of waking up to a four-figure bill.

Why I Keep Choosing Firebase

  • Fastest path from zero to working backend I have found -- real-time sync in minutes
  • Auth is dead simple and supports every provider you could need
  • Free tier is genuinely useful for real projects, not just toy demos
  • Crashlytics is the best free crash reporting on the planet
  • Emulator Suite makes local development and testing actually pleasant
  • Cloud Functions V2 fixed the cold start problem that used to be a dealbreaker
  • The integration between services -- Auth feeding into Firestore rules feeding into Analytics -- is where the real power lives

What Has Burned Me

  • Vendor lock-in is REAL -- migrating off Firestore means rewriting your entire data layer
  • NoSQL model with no JOINs forces painful denormalization for relational data
  • Billing can spike unexpectedly if you do not carefully design your read patterns
  • Security rules are powerful but debugging them is a nightmare
  • No full-text search -- you need Algolia or Typesense, which adds cost and complexity
  • Cloud Functions debugging in production is still just console.log and pray

The Cost Reality in Numbers

Spark plan: free. Covers development and small production apps comfortably. Blaze plan: pay as you go. Firestore reads cost six cents per 100,000. Writes cost eighteen cents per 100,000. Storage is about 2.6 cents per GB per month. Cloud Functions run forty cents per million invocations with 2 million free per month. Hosting is 2.6 cents per GB stored with 10 GB free and 360 MB of daily transfer free. Cloud Storage is 2.6 cents per GB with 5 GB free. Authentication is free for unlimited users on both plans, which is honestly remarkable.

For a practical estimate: a mobile app with 5,000 daily active users doing an average of 100 Firestore reads per session, generating 500,000 reads per day or 15 million per month, would cost about ninety dollars per month in Firestore reads alone. Add functions, storage, and hosting, and you are probably looking at a hundred to a hundred and fifty dollars total. That is very reasonable for a managed backend. Just make sure you budget for it and set up those alerts.

I should mention that Firebase's pricing is transparent but not intuitive. It is hard to predict your costs in advance because they depend entirely on usage patterns that are difficult to estimate before your app has real users. The pricing calculator helps, but real-world usage almost always differs from estimates. Build your app, watch the metrics for a month, and then you will have a realistic sense of what it costs.

My Score: 4.4 / 5

Firebase earns a 4.4 because it does exactly what it promises: it lets you build and ship apps absurdly fast, with a level of backend integration that no competitor matches. The Auth-Firestore-Functions-Analytics pipeline is a genuine productivity multiplier for mobile and web developers. Crashlytics alone is worth the price of admission. And the free tier is one of the most generous in the industry.

It loses the 0.6 for the NoSQL limitations that make complex data modeling painful, for billing that can surprise you if you are not careful, for vendor lock-in that makes the exit door feel like it is locked from the inside, and for developer tooling (especially debugging) that has not kept pace with the rest of the platform. But for prototyping, for MVPs, for real-time apps, for mobile-first projects, and for small teams that want to ship fast and worry about infrastructure later -- Firebase is still the answer. I keep choosing it. That says more than any score.

Comments (3)