Enabling seamless Firebase authentication across multiple web apps using Netlify
— DevOps, Software Development — 3 min read
In order to add authentication to Reciprocal.dev we’ve been using Firebase as the free tier gave us more than enough to get a basic app ready for alpha without paying a penny.
Reciprocal.dev is made of 3 different web apps; an Account Management app, User Journey Map Editing app and a User Journey Map Viewing app, and then we also have a marketing website.
In order to cleanly separate the apps I had original set them up to be served under different sub-domains (e.g. serving the account management app from account.reciprocal.dev) and while this worked there was one side-effect.
During testing of the app I became aware that the Firebase-based authentication wasn’t working across the sub-domains and it prompted the user to login again when navigating to an app they hadn’t previously used — not a great UX flow.
Reading into the issue, I discovered that while the Firebase console allows you to add a set of domain and sub-domains to the a list of authorised domains it won’t allow for authentication to persist among sub-domains that share the same parent domain.
There are some solutions people have put in place which involve using Firebase Cloud Functions to carry out the authentication step but I felt that this would be more effort and cost money if traffic increased so I decided to move all the web apps under the main reciprocal.dev domain.
Moving from sub-domains to paths on a domain
Netlify has a really well illustrated blog post on the different approaches that can be used to serve up different apps which I highly recommend reading as it’s a good insight into what’s possible via the _redirects
file.
An optional first step
When originally setting up the web apps in Netlify I hadn’t bothered to name them something that made sense and just left the auto-generated names in place.
In order to make it easier to understand what the apps actually did I renamed them as now they were to be served under a path and not a sub-domain this would be the only means of determining what they did.
Serving an app under a path
In order to serve apps under paths you’ll need to add a _redirects
file to the set of files that gets deployed via Netlify.
If you’re using a site generator (I’m using Gatsby) then this can get a little confusing as the _redirects
file needs to live in the static
folder (or wherever the files that get copied over at build time live) and not the root of the source code.
In order to serve an app under a path you add an entry (each line of the file is an entry) into the _redirects
file that matches the path and tells Netlify how to redirect the request and which HTTP status code to do this under.
The _redirects
entry will look like this:
1/app/* https://my-amazing-app.netlify.app/:splat 200
For serving up an app as if it was under the path we want to return a 200 status code and if the app being served up has routes of it’s own then we’ll also need to pass those over too using the :splat
value.
In the original Netlify blog they match against /app
instead of /app/*
but I found I needed to use the latter when serving up an app with it’s own routing (e.g. Originally https\://account.my.app/dashboard/me wouldn’t work under https\://my.app/account/dashboard/me without the extra wildcard) as it would try to serve a non-existent route on the marketing website without it.
Updating the app to work under a path
Now the website/app sitting on the root domain knows to serve up an app living on a different domain when a user goes to a path, the next step is to make sure that the app knows how to handle being served from that path.
The steps needed to be taken for this will vary between frameworks but a generic list of steps would be:
- Ensure that the root path your app is built against is prefixed with the new path so that it knows that its static assets are now accessible under a new path
- Update your routing to match against routes prefixed with the new path
- Update any redirects within or into the app from other apps
Personally I used create-react-app
to create the apps I need to serve so this involved:
- Adding a new environment variable to the Netlify build steps that set
PUBLIC_URL
to be the full URL the app would be served from - Adding a helper function to extract the path from the
PUBLIC_URL
so that I could prefix all calls to static assets and routing without the need to hardcode the value (as the path would be different during development)
Once I had made these changes then my apps worked perfectly under the new paths. If you have issues with your routing it might be worth checking that you have a _redirects
file in your app’s output folder that serves up the index.html
file from any route.
1/* /index.html 200
As this is required for path-based routing like react-router to work.
Outcome
Now I’ve moved my apps from being served from separate sub-domains to being served under separate paths on the same domain my Firebase authentication works seamlessly across all apps.
This means a user can log into one app, go to another without being prompted to re-authenticate, log out in that app and one going back to the original app find themselves logged out too.
It’s a shame that Firebase doesn’t support sub-domains out of the box but Netlify’s _redirects
file based approach made it really easy to move everything across.