Sveed
Docs

SvelteFireTS

Last updated: September 2, 2021

Installation

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.

  • Download the SvelteFireTS repo and copy the sveltefire folder into your src directory.
  • Add the $sveltefire alias to your vite config:
import path from 'path';
...
const config = {
  kit: {
    vite: {
      resolve: {
        alias: {
          $sveltefire: path.resolve('./src/sveltefire'),
        },
      },
    },
  },
};
  • Add the $sveltefire alias to your tsconfig.json:
{
  "compilerOptions": {
    "paths": {
      "$lib/*": ["src/lib/*"],
      "$sveltefire/*": ["src/sveltefire/*"]
    }
  }
}
  • Add your Firebase Config in one of 2 ways. One option is to paste your config directly into the 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.

  • Ensure you have the Firebase beta installed: npm install -D firebase@beta

Usage

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).

Firestore

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.

Documents

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>

Collections

<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.

Authentication

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}

Callable Functions

import { getFunctions, httpsCallable } from 'firebase/functions';
import { firebaseApp } from '$sveltefire';
const functions = getFunctions(firebaseApp);
const response = await httpsCallable(functions, 'helloWorld')('hello');

TODO

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:

  • Typescript Interfaces for Firestore Metadata and Users
  • Uploading
  • Firestore helper methods
  • Using Firestore’s REST API for SSR and preloading (did you know they had one! It’s terribly tricky to use but we have some helpers to make it easier)

Other Resources

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.