Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add formatting with Prettier #138

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches: [master, main]
pull_request:
branches: [master, main]

jobs:
build:
runs-on: ubuntu-latest
Expand Down
14 changes: 14 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.DS_Store
node_modules
/build
/dist
/.svelte-kit
/package
.env
.env.*
!.env.example

# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}
178 changes: 82 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SvelteFire

A minimal, yet powerful library that puts realtime Firebase data into Svelte stores.
A minimal, yet powerful library that puts realtime Firebase data into Svelte stores.

[Documentation](https://sveltefire.fireship.io)

Expand All @@ -15,7 +15,7 @@ A minimal, yet powerful library that puts realtime Firebase data into Svelte sto

<!-- 3. 📜 Get a Firestore document owned by a user -->
<Doc ref={`posts/${user.uid}`} let:data={post} let:ref={postRef}>

<h2>{post.title}</h2>

<!-- 4. 💬 Get all the comments in its subcollection -->
Expand All @@ -30,7 +30,7 @@ A minimal, yet powerful library that puts realtime Firebase data into Svelte sto

Svelte makes it possible to dramatically simplify the way developers work with Firebase. Here are some problems the project solves:

- Access users and realtime Firestore data as Svelte stores
- Access users and realtime Firestore data as Svelte stores
- Automatic subscription disposal to prevent memory/cost leaks
- Better TypeScript experience for Firebase
- Handle complex relational data between Auth and Firestore
Expand All @@ -45,9 +45,9 @@ npm i sveltefire firebase
```

```ts
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";

// Initialize Firebase
const app = initializeApp(/* your firebase config */);
Expand All @@ -59,32 +59,31 @@ export const auth = getAuth(app);

```svelte
<script>
import { auth } from '$lib/firebase';
import { userStore } from 'sveltefire';
import { auth } from "$lib/firebase";
import { userStore } from "sveltefire";
const user = userStore(auth);
</script>

Hello {$user?.uid}
```

3. Listen to realtime data.
3. Listen to realtime data.

Use the `$` as much as you want - it will only result in one Firebase read request. When all the subscriptions are removed, it will automatically unsubscribe.
Use the `$` as much as you want - it will only result in one Firebase read request. When all the subscriptions are removed, it will automatically unsubscribe.

```svelte
<script>
import { firestore } from '$lib/firebase';
import { docStore } from 'sveltefire';
import { firestore } from "$lib/firebase";
import { docStore } from "sveltefire";

const post = docStore(firestore, 'posts/test');
const post = docStore(firestore, "posts/test");
</script>

{$post?.content}
{$post?.title}
```

Or better yet, use the built in `Doc` and `Collection` components. See below.

Or better yet, use the built in `Doc` and `Collection` components. See below.

## Stores

Expand All @@ -96,50 +95,48 @@ Listen to the current user. Render UI conditionally based on the auth state:

```svelte
<script>
import { userStore } from 'sveltefire';
import { userStore } from "sveltefire";

const user = userStore(auth);
</script>

{#if $user}
<p>Hi {$user.uid}</p>
<p>Hi {$user.uid}</p>
{:else}
<p>Sign in...</p>
<p>Sign in...</p>
{/if}
```

### Firestore Stores

Subscribe to realtime data. The store will unsubscribe automatically to avoid unnecessary Firestore reads.
Subscribe to realtime data. The store will unsubscribe automatically to avoid unnecessary Firestore reads.

```svelte
<script>
import { docStore, collectionStore } from 'sveltefire';
import { docStore, collectionStore } from "sveltefire";

const post = docStore(firestore, 'posts/test');
const post = docStore(firestore, "posts/test");

// OR
// OR

const posts = collectionStore(firestore, 'posts');
const posts = collectionStore(firestore, "posts");
</script>

{$post?.content}

{#each $posts as post}

{/each}
{#each $posts as post}{/each}
```

Cast Firebase data to a TS interface:

```ts
interface Post {
id: string;
title: string;
content: string;
id: string;
title: string;
content: string;
}
const post = docStore<Post>(firestore, 'posts/test');
const posts = collectionStore<Post>(firestore, 'posts');
const post = docStore<Post>(firestore, "posts/test");
const posts = collectionStore<Post>(firestore, "posts");
```

## SSR
Expand All @@ -166,8 +163,8 @@ Second, pass the server data as the `startWith` value to a store. This will bypa
// Data fetched via server
export let data: PageData;

// Just give the store a startWith value
const post = docStore(firestore, 'posts/test', data.post);
// Just give the store a startWith value
const post = docStore(firestore, "posts/test", data.post);
```

## Realtime Components
Expand All @@ -187,10 +184,8 @@ The `FirebaseApp` component puts the FirebaseSDK into Svelte context. This avoid
</script>

<FirebaseApp {auth} {firestore}>

<User let:user></User>
<!-- other sveltefire components here -->

<User let:user />
<!-- other sveltefire components here -->
</FirebaseApp>
```

Expand All @@ -205,16 +200,14 @@ You can use Svelte's context API to access the Firebase SDK in any component.

### User

Get the current user.
Get the current user.

```svelte
<SignedIn let:user>
Hello {user.uid}
Hello {user.uid}
</SignedIn>

<SignedOut>
You need to sign in!
</SignedOut>
<SignedOut>You need to sign in!</SignedOut>
```

### Doc
Expand All @@ -223,26 +216,26 @@ Fetch a single document and listen to data in realtime. The `data` slot prop pro

```svelte
<Doc ref="posts/test" let:data let:ref>
{data.content}
{ref.path}
{data.content}
{ref.path}
</Doc>
```

Slot props can be renamed:

```svelte
<Doc ref="posts/test" let:data={post} let:ref={postRef}>
{post.content}
{postRef.path}
{post.content}
{postRef.path}
</Doc>
```

Firestore components can also handle loading states:

```svelte
<Doc path="posts/test">
<!-- data renders here in the default slot -->
<div slot="loading">Loading.... This will disappear when data is defined</div>
<!-- data renders here in the default slot -->
<div slot="loading">Loading.... This will disappear when data is defined</div>
</Doc>
```

Expand All @@ -252,10 +245,9 @@ Pass a `startWith` value to bypass the loading state. This is useful in SvelteKi
<Doc ref="posts/test" startWith={dataFromServer}>
```


### Collection

Collections provides array of objects containing the document data, as well as the `id` and `ref` for each result. It also provides a `count` slot prop for number of docs in the query.
Collections provides array of objects containing the document data, as well as the `id` and `ref` for each result. It also provides a `count` slot prop for number of docs in the query.

```svelte
<Collection ref="posts" let:data let:count>
Expand All @@ -272,49 +264,48 @@ Collections can also take a Firestore Query instead of a path:

```svelte
<script>
const myQuery = query(collection(firestore, 'posts'), where('test', '==', 'test'));
const myQuery = query(collection(firestore, "posts"), where("test", "==", "test"));
</script>

<Collection ref={myQuery} let:data>
</Collection>
<Collection ref={myQuery} let:data />
```

### DownloadURL

DownloadURL provides a `link` to download a file from Firebase Storage and its `reference`.
DownloadURL provides a `link` to download a file from Firebase Storage and its `reference`.

```svelte
<DownloadURL ref={item} let:link let:ref>
<a href={link} download>Download {ref?.name}</a>
<a href={link} download>Download {ref?.name}</a>
</DownloadURL>
```

### StorageList

StorageList provides a list of `items` and `prefixes` corresponding to the list of objects and sub-folders at a given Firebase Storage path.
StorageList provides a list of `items` and `prefixes` corresponding to the list of objects and sub-folders at a given Firebase Storage path.

```svelte
<StorageList ref="/" let:list>
<ul>
{#if list === null}
<li>Loading...</li>
{:else if list.prefixes.length === 0 && list.items.length === 0}
<li>Empty</li>
{:else}
<!-- Listing the prefixes -->
{#each list.prefixes as prefix}
<li>
{prefix.name}
</li>
{/each}
<!-- Listing the objects in the given folder -->
{#each list.items as item}
<li>
{item.name}
</li>
{/each}
{/if}
</ul>
<ul>
{#if list === null}
<li>Loading...</li>
{:else if list.prefixes.length === 0 && list.items.length === 0}
<li>Empty</li>
{:else}
<!-- Listing the prefixes -->
{#each list.prefixes as prefix}
<li>
{prefix.name}
</li>
{/each}
<!-- Listing the objects in the given folder -->
{#each list.items as item}
<li>
{item.name}
</li>
{/each}
{/if}
</ul>
</StorageList>
```

Expand All @@ -336,43 +327,38 @@ Upload a file with progress tracking
</UploadTask>
```


## Using Components Together

These components can be combined to build complex realtime apps. It's especially powerful when fetching data that requires the current user's UID or a related document's path.


```svelte
<FirebaseApp {auth} {firestore}>
<SignedIn let:user>
<p>UID: {user.uid}</p>

<h3>Profile</h3>
<Doc ref={`posts/${user.uid}`} let:data={profile} let:ref={profileRef}>

{profile.content}
<p>UID: {user.uid}</p>

<h3>Profile</h3>
<Doc ref={`posts/${user.uid}`} let:data={profile} let:ref={profileRef}>
{profile.content}

<h4>Comments</h4>
<Collection ref={profileRef.path + '/comments'} let:data={comments}>
{#each comments as comment}
<strong>{comment.content}</strong>
{/each}
<h4>Comments</h4>
<Collection ref={profileRef.path + "/comments"} let:data={comments}>
{#each comments as comment}
<strong>{comment.content}</strong>
{/each}

<div slot="loading">Loading Comments...</div>
</Collection>
<div slot="loading">Loading Comments...</div>
</Collection>

<div slot="loading">Loading Profile...</div>
</Doc>
<div slot="loading">Loading Profile...</div>
</Doc>
</SignedIn>

<SignedOut>
<p>Sign in to see your profile</p>
<p>Sign in to see your profile</p>
</SignedOut>
</FirebaseApp>
```


## Roadmap

- Add support for Firebase Storage
Expand Down
Loading