Firebase Custom Authentication With No Backend

Building an Army of Static Sites With Live Data

Adam Neary

I am uncertain if our use of Firebase is an edge case or an awesome case, but I will leave that to you. Here is our situation:

  1. We have a typical API (Node/Express) that authenticates users and provides CRUD actions for a dozen models
  2. We have tons of information running outside the API (e.g. we display consultant profile views to prospective employers), so we want to use Firebase as a realtime caching layer updated by both the API and our event stream (and we are just getting started!)
  3. We want to decompose our monolithic Single Page Application into a handful of manageable UI projects without having to create a different backend for each

Though Express is currently still serving up a decent amount of markup, those days are numbered. Our end game is for all (or most!) front end code is to have simple projects compiled by gulp, deployed statically, and pointed to by DNS. No backend for them whatsoever (in fact, in the near term we can push each repo to Github Pages and call it a day).

These UI projects are logical modules in the user experience: Creating a profile, reviewing candidates for a project you have posted, managing contracts, managing payments, etc.

Delivering Firebase Tokens From the API

Since users are already logging into our API, we wanted to use Firebase Custom Authentication, which is documented well here. It really is as simple as they make it sound. We just added an endpoint for the token:

app.get(‘/firebase’, api.firebase);

And then we handle this with the following:

Simple.

Requesting a Token from the Client

This in place, the client can retrieve a token with an XHR request and authenticate with Firebase prior to initializing the javascript application itself.

The only trouble we encountered was CORS-related, but this was solved by the with xhrFields: {withCredentials: true}. This passes our API session credentials with the request, and we are there. On the server end, we add the complementary res.header(‘Access-Control-Allow-Credentials’, true) and we are there. Of course we have a bit of cleanup ahead to make this a bit more production ready, but you get the idea.

Then, depending on the UI project, initializeApp() might pass control to a Backbone app, render a React component, or whatever we like. Since each project is isolated, we can tackle this case by case based on the needs of the module.

Deploying a Data-Enabled Static Site

We have only begun scratching the surface of what is possible here, but beyond the API — which itself has a very contained set of responsibilities — we can compile a front-end project to a static set of assets using gulp, and can push those assets to the gh-pages branch, where the universe can access them. In the next iteration, we may use S3 and Cloudfront, but for now Github Pages is delivering a solid experience. Just ask New Relic!

Then, we point a subdomain to that page, and when users access them, they can safely make requests to our API for any of our data models. And they can authenticate into Firebase, where we can get particularly nasty with React components using ReactFire.

If a user is not authenticated, we redirect to our login page (also static). Done and done.

Separating Concerns…and Engineers

The real beauty of this approach is that it frees up backend-oriented engineers to focus on the event stream and the various micro-services that magically coordinate a beautiful symphony of file uploads, interactions with the LinkedIn API, and so on. Our Data Scientist (oh man, before long I will get to say “Data Team”) can focus on realtime recalculation of our scoring algorithm and the various features on which it should rely.

Meanwhile, front end-oriented engineers can focus on delivering world class UI experiences knowing that Firebase is always up to date with everything they need. React components could not be easier to bind, so this frees us up to focus on the heart of the matter, making it easy for our users to get things done.


Big thanks to https://github.com/alekseykulikov for helping us figure some of this out. I really thought the API session token situation was going to be a lot more complicated, and I was psyched about how simple the end solution ended up being.


If you found this article useful, please feel free to get your recommend on…

    Adam Neary

    Written by

    Software engineer @airbnb. Dad, pizzaiolo.

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade