Mastering Client-Side Authentication with Firebase and SvelteKit

Justin Ahinon
Last updated on
Table of Contents
SvelteKit version: 1.5.0
Firebase version: 9.19.1
GitHub repository: https://github.com/JustinyAhin/okupter-repos/tree/main/apps/sveltekit-auth-firebase
Demo site: https://sveltekit-auth-firebase.vercel.app
Navigating the world of user authentication can be daunting, especially when you're trying to create a seamless and secure experience for your users. If you're building a SvelteKit application and looking for a reliable, easy-to-integrate solution, then Firebase might just be the answer to your prayers . In this blog post, we'll delve into the exciting realm of SvelteKit authentication with Firebase.
We'll explore:
Setting up your SvelteKit project and integrating Firebase
Choosing and implementing the right authentication method
Creating user-friendly login and registration components
Protecting your routes with route guards
And finally, logging users out and managing their authentication state
Whether you're new to SvelteKit and Firebase or looking to enhance your existing project, this guide will walk you through each step to make user authentication a breeze. So, strap in, and let's unlock the full potential of SvelteKit client-side authentication with Firebase!
Setting up the project
In this section, we'll set up a new SvelteKit project with TypeScript, install Firebase, and configure it within our project.
Create a new SvelteKit project
To get started, open your terminal and run the following command to create a new SvelteKit project with TypeScript using
pnpm
:
When going through the CLI option, make sure to choose TypeScript. Trust me, you'll thank me later. TypeScipt with SvelteKit is a delightful experience .
Install and setup Firebase
Once inside your new project directory, run the following command to install Firebase:
Before you continue, be sure to create an account on firebase.google.com and create a new project and a new app.
Create a new
firebase.ts
file in the
/src/lib
folder.
What we are doing here is importing Firebase modules to initialize a new app, and create an authentication wrapper.
Notice that we are checking here that if
getApps().length
is undefined before we create a new app. This is because during navigation, the app could be created many times, and we don't want conflicts that could trigger errors later on.
Also, notice that the environment variables here are prefixed with
PUBLIC_
.; since the Firebase keys and app details can be safely exposed to the client.
You can get these theses variables from your Firebase app console.
Check out this blog post to learn more about how environment variables work in SvelteKit: https://www.okupter.com/blog/environment-variables-in-sveltekit
Now that our SvelteKit project is set up with Firebase and TypeScript, we're ready to move on to the next section: choosing and implementing the right authentication method.
Firebase authentication methods
Firebase offers a variety of authentication methods to suit your application's needs. In this section, we'll briefly discuss some of the most popular methods and then focus on implementing email/password authentication for our SvelteKit app.
Email/Password: Allows users to sign up and sign in using their email address and a password.
Google Sign-In: Lets users sign in with their Google accounts.
Facebook Login: Enables users to sign in with their Facebook accounts.
Twitter Login: Allows users to sign in with their Twitter accounts.
GitHub Login: Permits users to sign in with their GitHub accounts.
Phone Number Authentication: Authenticates users using their phone numbers and SMS verification.
There are even more methods available, but these are some of the most commonly used. For this tutorial, we'll focus on email/password authentication.
You can learn more about the different authentication methods here .
Enabling email/password authentication in your Firebase app
Once you get your new Firebase app up, you can enable the email/password authentication like this:
Go to the Firebase Console and select your project.
Click on "Authentication" in the left sidebar.
Navigate to the "Sign-in method" tab.
Scroll down to find "Email/Password" and click on the edit icon (pencil) to enable it.
Toggle the "Enable" switch and save your changes.
Creating Auth Routes: Login and Registration
Now, let's create the necessary routes for our login and registration components. Both pages will have a form with email and password fields, and a submit button.

And for the login route:
Notice that we are binding submission on the forms to two functions
register()
and
login()
that we are going to use to handle the logic.
We are also binding the input values with the variables:
let email: string
and
let password: string
.
Handling registration and login logic
For the user registration, we will use the
createUserWithEmailAndPassword()
function from Firebase. It takes the authentication wrapper, the email, and the password as arguments.
We are also using
goto()
here to redirect to the login page in case the sign-up is successful. Else, we just log the errors in the console.
In addition, we also set up the value of the reactive variable
success
to false in case of an error.
This allows us to display custom error messages to the user when something goes wrong:

We can customize more these errors, by getting the error code, and generating custom messages depending on the scenario.
In case you need to do something with the user credentials after the sign-up process, you can add this variable inside the
then()
statement. It will look like this:
Let's now look at the login logic:
This is pretty much similar to the registration logic, except we are using the
signInWithEmailAndPassword()
function.
So, that's it. We just did registration and login with Firebase. But that's not enough (fortunately). Notice that we are redirecting to a
/protected
route in case of a successful login.
That means we need to find a way to pass the login state to this route, and other places in our application that might need it .
Making use of Svelte stores
Svelte stores are a cool way to share states across Svelte applications. They are used to create variables that are reactive, and can be shared, updated, and synced pretty much everywhere in your Svelte app.
To start, let's create a
src/lib/authStore.ts
file with the following content:
A
writable
in Svelte is a function that creates a store for which the value can be updated later on. It's perfect for our use case.
Here we are creating a
writable
store with the default value of
undefined
. We are also typing this store to get auto-completion and type-safety later on.
Now, we can add this store to our login logic. What we want is to save the logged-in user email and identifier in the store when the operation is successful:
Since a writable store is a function, we can not access its value as others JavaScript variables. That's why stores come with some functions to
set
and
update
their value, but also to
subscribe
and
unsubscribe
to their change.
On top of that, Svelte uses the less verbose
$
symbol to automatically subscribe and unsubscribe to the value of a store.
That's what we are using in the snippet above.
Guarding the protected route
Now, we are ready to create a protected route and guard it appropriately.
Let's create a simple
src/routes/protected/+page.svelte
file for the component and
src/routes/protected/+page.ts
for the authorization logic:
As you can see there, we are importing the store, subscribing to its value, and redirecting to the login page if there is no user.
And we unsubscribe from the store right after. Every time a non-authenticated user will try to access that route, they will be automatically redirected to login.
Login out
The last thing to add now is the logout feature. Here again, Firebase comes to the rescue with a function that does exactly that.
I'm going to add the login button in the
src/routes/+layout.svelte
file:
The
handleLogout()
function uses the
signOut()
method from Firebase. In addition, we set the
authUser
store value to undefined.
Persisting Authentication State with Firebase
Svelte stores make managing state easy, but the state is not persisted on page refreshes. Fortunately, Firebase offers built-in options for handling auth state persistence. This way, users stay authenticated even after reloading the page or returning to the app later.
In an upcoming post, I'll explore Firebase's auth state persistence features and demonstrate how to integrate them into your SvelteKit app for a seamless authentication experience. For more information, check out the official Firebase documentation.
Wrapping up
In conclusion, implementing client-side authentication with Firebase and SvelteKit is an effective and straightforward process . By utilizing Firebase's robust authentication methods and SvelteKit's simplicity, we've managed to create a secure and user-friendly authentication system. Additionally, incorporating Svelte stores into our application has allowed us to maintain a shared state for authentication, making it easier to manage user login and logout events.
If you're looking to bootstrap your startup or product with Svelte, or simply want to level up your Svelte and SvelteKit skills, I offer consulting services tailored to your needs. With my expertise in Svelte and SvelteKit, I can help you build secure and efficient applications like the one we've discussed in this article. To learn more, visit my Svelte and SvelteKit consulting page.
With this knowledge, you're now equipped to create a robust and secure SvelteKit application that makes the best use of Firebase authentication. As you continue to develop your project, remember to keep security in mind and make use of the available tools and best practices to ensure the safety of your users' data. Happy coding!