Firebase login with Google in plain javascript

David Dikman
5 min readFeb 25, 2022

I use Firebase auth for my JReader app, SEORank as well as my daytime work app FACY. I love how it makes securing your app easy and it is incredibly powerful.

Combine the auth events with Firebase functions and you can control user membership lifecycles such as sending welcome emails or cleaning up data on deletion. You can also easily use the Firebase auth to secure APIs either inside or outside of Firebase.

This is what brings me to write this article. I use Firebase auth to secure most of my backend but I have found it a pain to get those JWT tokens without having some small tool to help out.

A while back I created a small app and wrote an article about this. However, this was only to get the JWT, not to use it in some tool. As I have got into writing small self-contained PoCs and MVPs lately this is something I was keen to solve and in this post, I want to share with you the conclusion I came to.

Getting a JWT is easy peasy

I think many now have a gmail. This makes login as simple as a button press. This is brilliant because it removes a lot of logic to create a login user interface. Compare it with an email and password, not only is it slow and annoying to input but it also means several new components for you to add, validate and pass data from.

Next up, the code to trigger login with google is really simple. So what I want to propose is to wrap this up neatly in a small javascript include that you can plug into your tool and completely abstract away that login concern and focus on what your tool needs to do.

Using this, the following is all you need to login and use your JWT:

Example usage (open code here)

The code

I have written a small Javascript file that you can copy and include in your own single-file HTML tools. You can find the source code in the repository below.

The code actually does very little but it takes care of the following:

  1. Defines specifically what three minimum parameters you need, the project ID, API key and auth domain
  2. It hooks up the events required for login and logout so that you can control your UI changes based on it
  3. It wraps login and logout functions into a single simple function call
  4. As long as you initialise this on page load, any previous login will automatically re-login and refresh the token

How it works

Let us break down the contents in firebase-auth.js bit-by-bit.

function initFirebaseAuth(config) {
if (!config.projectId) throw Error('Missing projectId');
if (!config.apiKey) throw Error('Missing apiKey');
if (!config.authDomain) throw Error('Missing authDomain');
const firebaseConfig = {
apiKey: config.apiKey,
projectId: config.projectId,
authDomain: config.authDomain
}
firebase.initializeApp(firebaseConfig);
firebase.auth().onAuthStateChanged(async function(user) {
if (!user && config.loggedOut) {
config.loggedOut();
return;
}
if (!config.loggedIn) return;
const token = await user.getIdToken();
config.loggedIn(user, token);
});
}

Most of the magic happens in this function which you should call as soon as your DOM has loaded. It takes three parameters and an optional loggedIn and loggedOut callbacks.

By listening to changes in the login-state by subscribing to onAuthStateChanged we can change our UI by handling the state change in loggedIn and loggedOut callbacks.

This way, regardless of whether the state changes due to the user pressing login or logout or if we are already in logged-out or logged-in state when opening the page, the user interface will be the same.

Either callback will be called shortly after the initFirebaseAuth method has been called. There is a slight delay though as Firebase will try to re-login if previously logged in.

Firebase will automatically save the logged-in user details in local storage until we log out. For this reason, if you hook up the loggedIn method, any time after login that you refresh your page, firebase will automatically re-login after begin initialised.

The next parts are the login and logout methods, these are fairly self-explanatory, the only thing to mention here is the error handler. I do this specific logic for the most common error I’ve found, that your domain isn’t added to the list of approved domains in Firebase project settings:

function handleAuthError(error, onError) {
if (error.code === "auth/unauthorized-domain") {
const authDomain = firebase.auth().app.options.authDomain;
const projectName = authDomain.replace('.firebaseapp.com', '');
onError(new Error(`Looks like your domain isn't valid for this project. Please check your Firebase Auth domain configuration. https://console.firebase.google.com/u/0/project/${projectName}/authentication/providers`));
} else {
onError(error)
}
}

Trying it out

You can try this out with your own project configuration using the example interface:

https://ddikman.github.io/firebase-gmail-auth/example.htm

Add ddikman.github.io to your approved domains and copy the project settings into the user interface above and you should be able to login.

The example app interface, asking for firebase settings before logging in

Bear in mind though, you don’t want to allow my poor old Github account to login into your systems (not that I would) so make sure to remove the domain from the approved list afterwards.

Or better yet, clone this repository and run it locally. The instructions are in the readme. It works the exact same way only your project is likely already configured to allow requests from localhost so as long as you open it in localhost:8080 (if hosting with http-server) you should be good to go with no further configuration.

Any questions on that?

That’s it for this post. I hope the example above can help you get started or help troubleshoot your own setup by providing a working example.

If you have any questions or so, let me know in the comments below.

Also, check out my other posts about Firebase on counting firebase logins or maybe using Firebase functions with triggers.

Thank you for reading!

--

--

David Dikman

Full-stack developer and founder. Writing here and at https://greycastle.se. Currently open for contract work.