Last updated: September 2, 2021
Because Firebase 9 beta and Vite still don’t play nice together in SSR, we can’t npm install
the SvelteFireTS files just yet. In the meantime, we must copy the package into our project as if it was part of our lib.
sveltefire
folder into your src
directory.$sveltefire
alias to your vite config:import path from 'path';
...
const config = {
kit: {
vite: {
resolve: {
alias: {
$sveltefire: path.resolve('./src/sveltefire'),
},
},
},
},
};
$sveltefire
alias to your tsconfig.json
:{
"compilerOptions": {
"paths": {
"$lib/*": ["src/lib/*"],
"$sveltefire/*": ["src/sveltefire/*"]
}
}
}
sveltefire/config.ts
file. A more flexible option that will serve you well when Firebase/Vite improvements enable this library to be published to npm is to add a .env
to your project root, replacing the ...
with the appropriate values:VITE_FB_apiKey=...
VITE_FB_projectId=...
VITE_FB_messagingSenderId=...
VITE_FB_appId=...
VITE_FB_measurementId=...
That latter option also allows you to easily use different Firebase projects in different environments if you take advantage of SvelteKit’s environment variables.
npm install -D firebase@beta
From within any file you can now import { firebaseApp, db } from "$sveltefire";
and use either as needed. The library is set up such that nothing will happen server-side, and whatever component first uses one of these will also end up initializing Firebase (it’s like a singleton service).
There are a lot of undocumented Firestore convenience helpers you can see in action in the Living Dictionaries web app, a SvelteKit production app (search the repo for imports from the $sveltefire
directory), but here is how to use the Svelte Firestore real-time components to listen to Documents and Collections.
Thanks to the recent addition of Generic Types to Svelte components, if you startWith
a typed property (it can be undefined or it could be data fetched via page load), the resulting data from the Doc
real-time listener component will have the same type, enabling you to use intellisense.
<script lang="ts">
import Doc from '$sveltefire/components/Doc.svelte';
import type { IMessage } from '$lib/interfaces';
let initialMessage: IMessage;
let messageId = 'abcd';
</script>
<Doc
path={`messages/${messageId}`}
startWith={initialMessage}
let:data={message}>
{message.title}
</Doc>
<script lang="ts">
import Collection from '$sveltefire/components/Collection.svelte';
import type { IMessage } from '$lib/interfaces';
let initialMessages: IMessage[];
</script>
<Collection
path={`messages`}
startWith={initialMessages}
let:data={messages}>
{#each messages as message}
{message.title}
{/each}
</Collection>
The original SvelteFire (JS version) library built by Jeff Delaney has documentation for how to use these Collection and Doc components as well as the underlying stores, and it is still accurate.
Import the FirebaseUiAuth.svelte
component wherever you’d like to add your signup/sign-in flow using Google Login or Email (it’s trivial to turn on other providers, I just haven’t done it yet - feel free to submit a PR to the repo that makes them configurable). I’m doing it inside of a modal like this:
<script>
import FirebaseUiAuth from '$sveltefire/components/FirebaseUiAuth.svelte';
import { updateUserData } from '$sveltefire/helpers/updateUserData';
import Modal from '$svelteui/ui/Modal.svelte';
</script>
<Modal on:close>
<span slot="heading">Sign In</span>
<FirebaseUiAuth
on:close
on:updateuserdata={(e) => updateUserData(e.detail.user, e.detail.isNewUser)} />
</Modal>
And then I am lazy-loading that component (and thus the FirebaseUi + Firebase 8 scripts also lazy-load from a CDN - FirebaseUi will not upgrade to using Firebase 9 until it is out of beta, but you’re not here because you’re the type who likes to wait for that):
{#if showLogin}
{#await import('./AuthModal.svelte') then { default: AuthModal }}
<AuthModal on:close={toggle} />
{/await}
{/if}
import { getFunctions, httpsCallable } from 'firebase/functions';
import { firebaseApp } from '$sveltefire';
const functions = getFunctions(firebaseApp);
const response = await httpsCallable(functions, 'helloWorld')('hello');
I’m releasing this post because so many are asking about SvelteKit and Firestore 9. The above was a first stab at documenting things but there is a lot more available in this library that is yet to be documented:
Until I finish the documentation here, please visit the documentation for the Firebase 9 Alpha - some may start to go out of date, but I find it far more helpful and easy to use than Firebase’s regular documentation.
As noted in the repo, Jeff Delaney gets most of the credit for SvelteFireTS. I started with SvelteFire then added Typescript and borrowed some convenient helpers from Firestore Advanced Usage Angularfire - you can access that if you sign up at Fireship.io. While you’re there, you should subscribe to the Fireship Youtube Channel for some great tutorials (unaffiliated plug).
As previously mentioned, see the Living Dictionaries web app, a SvelteKit production app for more usage examples.