What I Wish I Knew Before Using Firebase in a Real Project


Firebase is often recommended for rapid development — and for good reason. It offers backend services like authentication, a real-time database, Firestore, hosting, and even serverless functions — all in one platform.
But once I tried to use Firebase in a real project beyond the usual tutorials, I realized there were quite a few things I hadn’t thought about.
This article summarizes what I learned — not to discourage you from using Firebase, but to help you plan better.
🔐 1. Authentication: Simple Setup, Complex Logic
Firebase Authentication is incredibly fast to set up — email/password, Google, and more are just a few lines away. But in real projects, managing authentication properly is not trivial.
Challenges I faced:
Persisting auth state on refresh
Securing routes based on user roles (e.g., admin, editor)
Handling token expiration and silent reauthentication
Syncing authentication state across tabs
✅ What worked for me:
Using
onAuthStateChanged()
in a global auth contextCaching custom claims or roles in localStorage or Firestore
Protecting routes using a higher-order component (HOC) or custom hook like
useAuthGuard
🔒 Lesson: Setup is easy, but secure, role-based routing takes planning.
🧱 2. Firestore Schema Design Is Critical
Firestore doesn’t have a fixed schema, but that flexibility can backfire if you don’t design your collections based on queries.
My mistakes:
Creating deeply nested subcollections that were hard to query
Storing large documents with arrays of objects (bad for reads)
Forgetting Firestore has read limits, and nested data counts too
✅ What helped:
Designing flat collections:
/users
,/posts
,/tasks
, etc.Using document references instead of nesting
Planning indexes in the Firestore console to support custom queries
📊 Lesson: Design your data around how you want to read it, not how you mentally group it.
💸 3. Free Tier Isn’t Free When You Don’t Optimize
Firebase gives generous free tiers, but I didn’t realize how fast reads could pile up.
Where I went wrong:
Using
onSnapshot()
for data that didn’t need real-time updatesPlacing multiple listeners on the same collection (from multiple components)
Not caching data locally
✅ What I changed:
Switching to
getDocs()
for static dataAdding guards like
if (!dataExists)
before setting new listenersDebouncing form inputs before writing to Firestore
💰 Lesson: Every read, write, and listener counts. Monitor usage in the Firebase console and optimize early.
🚀 4. Firebase Hosting Is Fast but Has Its Limits
Firebase Hosting is great for frontend apps — fast deploys, SSL, and easy CDN usage.
But I ran into limitations when I needed:
Custom headers for caching or security
Server-side logic or API gateways
Proxying third-party APIs
✅ Alternatives I now consider:
Use Firebase Hosting for static frontend (React/Next.js)
Use Cloud Functions for APIs or backend logic
Or consider Vercel/Render if SSR is needed
📦 Lesson: Use Firebase Hosting for speed, but know when to bring in other tools.
🧠 5. Using Firebase with React Needs Clean Architecture
When your app scales, Firebase calls spread across components become a mess.
What helped:
Creating a
services/firebase.js
to wrap all Firebase functionsUsing React Context to manage auth, theme, or user data
Organizing code with folders:
components/
,pages/
,services/
,hooks/
,utils/
🧱 Lesson: Keep Firebase logic away from your components. It improves reusability, testing, and debugging.
📈 6. Analytics, Logs, and Debugging Aren’t Built In
Firebase gives you some logs in the console, but not enough for real debugging. I ended up:
Missing silent failures in functions
Not tracking auth usage properly
Lacking custom analytics for usage patterns
✅ My workaround:
Use
console.log()
+ Firebase's debug modeEnable Google Analytics + set up custom events
Add error boundaries and fallback UI in React
📊 Lesson: Firebase helps you build fast, but you’re still responsible for observability.
🎯 Final Thoughts
Firebase is an amazing tool when used correctly. It gave me speed and flexibility — but also taught me some hard lessons about planning, structure, and optimization.
If you're about to start a real Firebase-based project, ask yourself:
Do I know how to model this data for reads?
Do I need real-time updates or just fetch-on-load?
How will I manage authentication across components?
What happens when my usage grows?
This post is part of my #2Articles1Week challenge. I’m writing and sharing what I learn along the way — from mistakes, real projects, and hands-on experience.
Thanks for reading!
Feel free to share your Firebase lessons in the comments
DevThoughts - Learning by building, sharing by writing.
Subscribe to my newsletter
Read articles from Thanusha Gali directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Thanusha Gali
Thanusha Gali
CS undergrad | Web Dev & AI enthusiast | Specializing in Blockchain Engineering for Web3| Writing my dev journey one blog at a time 🚀 Let’s connect & grow → #DevThoughts