I'm trying to build a Svelte/SvelteKit web app that requires authentication. For this I'm using Firebase Authentication.
I can successfully create a new user and sign into the web app, but I cannot find a way to persist the authenticated state.
I have my firebase.server.ts
file in src/lib/server
:
// Initialize Firebaseconst app = initializeApp(firebaseConfig)const storage = getStorage(app)const auth = getAuth(app)const firestore = getFirestore(app)auth.onAuthStateChanged((user) => { if (user) { console.log('Auth state changed to true') authUser.set({ isLoggedIn: true, user: user }) } else { console.log('Auth state changed to false') authUser.set({ isLoggedIn: false, user: undefined }) }})export { storage, auth, firestore }
I set the authenticated state in a writable
called authUser
.The authUser
is placed under src/stores/
and looks like this:
import type { User } from 'firebase/auth'import { writable } from 'svelte/store'interface AuthUser { isLoggedIn: boolean user: User | undefined}let authUser = writable<AuthUser | undefined>(undefined)export { authUser }export type { AuthUser }
And in my +layout.svelte
in src/routes/
I have this:
<script lang="ts"> import { enhance } from '$app/forms' import { authUser } from '$lib/stores/authStore' import '../app.css'</script><div class="px-40"><header class="py-4 space-x-8 w-full bg-red-400"><a href="/" class="font-semibold hover:underline">Home</a><a href="/signup" class="font-semibold hover:underline">Sign up</a><a href="/login" class="font-semibold hover:underline">Login</a><p class="flex self-start">You are logged {$authUser?.isLoggedIn === true ? 'in' : 'out'}</p><p>{$authUser?.isLoggedIn}</p><form method="POST" use:enhance><button type="submit" formaction="./?/logOut">Log out</button></form></header><main class="py-20"><slot /></main></div>
I expected that whenever I would log in, that onAuthStateChanged
would trigger and a new state would be set on authUser
, and it actually works. My consol.log()
s confirms that.
But whenever I load the page I can see the text i expect to see, i.e. "You are logged in" for 1 millisecond before it changes to "You are logged out"
So what is the issue here? Why does the state change?