It’s been 4 months since I started playing with Firebase for Web. 122 days of dev work that ended with despair, or my longing to old tech stack that simply works.

Sure, Firebase is all pretty and beautiful branded, blended into Google Cloud and full of articles, videos and guides to walk you through. It is, however, too much of a paradigm shift that cripples your ability to innovate.

In no particular order:

Authentication

Firebase promise

Offload all security procedures (registration, email verification, login, sign out) and support federated, social sign-in providers, including email/password and phone verification.

In reality..

Only easy if you implement FirebaseAuthUI, which has a UI that is out of context and intolerable if you care about UX. Phone verification for example (albeit free, requires ugly ReCaptcha) and the AccountChooser (albeit great concept) opens in a completely Google design. Social plugins change all the time and to use the most up to date (like this awesome “Continue as {{Name}}” button) you have to implement the providers’ own JavaScript and other necessities and do a lot of work to make them work together. You can’t easily add claims (groups, roles, feature toggles, etc.) to user’s json web token, meaning you have to create and supplement each authentication with a call to the Real-time database. Basic logins and provider data will be on Firebase “internal” authentication database (who backs this up I have no idea) while actual user data will still be maintained by yourself on a “user” node. Browsing and deleting user logins can be quite cumbersome. Outgoing emails (welcome, reset password) looks bad and can’t be customized to your site’s brand.

Database

Promise

Store unlimited data, query it securely with no servers and in real-time.

Reality

Querying on anything beside a simple key lookup is a pain in the bum. Somewhere, someone understands how indexing, pagination and multi-filtering works but I’ve given up. Don’t forget you do all of this client-side (JavaScript). Firebase returns data as “snapshot”, a very weird, encoded structure that is not easily iterative. You have to navigate between forEach, snapshot.key and snapshot.val() to get what you want. I thought that’s the whole point of using JSON. Write errors are a pain to debug, even with debugging enabled ends up as JavaScript “permission denied” with no way knowing. You have to run your payload against the simulator to get the firebase rule line you had tripped on. There’s no easy way to cache data, especially fragments that requires high computation. Why would a call to the same unchanged node by the same user not return from cache? REST interface will not use the signed-in user’s credential. You have to pass it as a token (which is just weird, especially if you planned to build a simple CRUD on top of firebase serverless REST paths). Firebase-admin is ignoring your database validation rules, who’s idea is that I have no clue but it caused me much grief. On the plus size, the rule systems is indeed powerful. You can import/export JSON to just about any node and can easily turn on daily backups.

Hosting

Promise = Reality

No rants here, really. Static files seem to load fast, deployment is easy and there’s good support for redirects, rewrites and even custom headers (i.e for caching). Setting up CNAMEs and free SSL was a breeze. You do have to learn a new set of directives.

Cloud Functions

Promise

Extend your static (client-side) website with every functionality you can dream of.

Reality

Local testing only works for HTTPS. Debugging every little bit feels like a murder-mystery. You have to deploy, execute, refresh logs in dashboard and use lots of console.log because that’s the only way to debug something somewhere in a server that isn’t yours. No cron jobs, I ended up setting an HTTPS handler and used another physical server to curl it every 5 minutes Deployment is really buggy. You occasionally see cryptic “Server Error. socket hang up” messages. Then you try again (and again).

Which brings us to server-less

Promise

Save hundreds of $$$ and remove that awfully complex middle-tier of web/app-servers and load-balancers. Actively upgraded, managed and scaled for you.

Reality

You are forced to do everything client-side (a.k.a browser’s JavaScript), including your SECRET SAUCE (business rules, experiments, even database schema), and where’s there’s opening, bad people can take advantage or you have to do the extra work to prevent it. You get a crippled, detached server-side environment. Want to send a contact form? have a JavaScript function write a message to a PubSub queue and ingest it, or store a temporary document on the real-time database. Want to do fancy/shmansy stuff like shipping log files to BigQuery, running predictions or simply processing the page before the user sees it? you probably can’t or it will take you considerably more time. You get a 2nd-grade big json file as your database. You will not be able to do reliable multi updates, complex queries or pagination. It might be too large to take away at some point. Remember this is your own data. Somewhere down the road, you’ll be surprised with your Firebase bill, because really who knows how these things are charged. Hopefully it won’t be too late for you to bail.

Update: my current stack

Google Compute running pm2 for large (>1000 RPS) projects, otherwise Google App Engine Flexible Env Monolith Node.js application running Express (microservices might be sexier but deserve another rant post) Home-brewed REST middleware (basic get/post controllers, everything that can be done server-side is done server-side) MySQL for metadata (with some tweaks, i.e meaningful string IDs, JSON columns for arrays, created/updatedAt timestamps, 1 user and 1 super-user connections, stuff like that) In-process (a.k.a RAM) cache for stuff I read a lot (MySQL is hardly accessed directly by users) Redis for real-time counters JWT for user sessions JSON event/log files rotated directly to BigQuery (used to be AVRO) Some PWA practices but not SPA ES5 client-side JavaScript, CDN includes (no shitty webpack) Some Vue.js if I feel like it

Looking to hear your thoughts. Discussion is also on HackerNews.