How to add Firebase auth listener to SvelteKit

I’ve been working on an application for alfatoro.com and decided to use SvelteKit and Firebase with it. And as I’m attempting to add the authentication layer, vite has been throwing a lot of errors to me:


[vite] Error when evaluating SSR module /src/lib/to/file/path

It seems like the problem is that Firebase has some client only utility that are not server-side friendly. So how do we fix this issue?

The answer is actually really simple. Initialize Firebase & and add onAuthStateChange() listener to the onMount function that Svelte provides!

Let’s do a simple step-by-step guide on how to add Firebase Auth to a SvelteKit app.

Step 1: Create an auth.svelte component

I like to create a auth.svelte component in the `src/lib/components` directory. This will be used in the __layout.svelte components since it’s the first parent component to each route in the app.

Step 2: Initialize Firebase inside the onMount hook

The next step is to import the utility function initializeApp() and getApps() inside your auth.svelte file.


<script>
  import { onMount } from 'svelte';
  import { initializeApp, getApps, } from 'firebase/app';

  onMount(() => {
    if (!getApps().length) {
      initializeApp({
        // Firebase configurations
      });
    }
  });
</script>

I’m first checking to see if any apps already exist before evocating initializeApp() by checking if getApps() returns an array with elements.


if (!getApps().length) {
  // initializeApp()
}

If getApps() returns 0 then I will execute the initializeApp() function.

Step 3: Add Firebase onAuthStateChanged listener


<script>
  // ... previous imports
  import { getAuth } from 'firebase/auth';

  onMount(() => {
    // ...initialize code

    const auth = getAuth();

    auth.onAuthStateChanged(user => {
      if (!user) {
        return;
      }

      console.log('user meta data:')
      console.log('user uid:', user.uid)
      console.log('user display name:', user.displayName)
      console.log('user email:', user.email)
    })
  });
</script>

The next step I took is to import the getAuth() utility function from the firebase/auth library


import { getAuth } from 'firebase/auth';

I then invoked the function and added the onAuthStateChanged() listener to the same onMount hook that we used in step 2.


const auth = getAuth();

auth.onAuthStateChanged(user => {
  if (!user) {
    return;
  }

  console.log('user meta data:')
  console.log('user uid:', user.uid)
  console.log('user display name:', user.displayName)
  console.log('user email:', user.email)
})

Step 4: Import auth.svelte in the root __layout.svelte component

The final step is to place this in the root of the __layout.svelte component so every page you create can have access to this listener.


<script>
  import Auth from '$lib/components/auth.svelte';
</script>

<Auth />

I like to tweet about Svelte and post helpful code snippets. Follow me there if you would like some too!