Skip to content

Commit 0fd7524

Browse files
committed
docs: update readme
1 parent f0d5b91 commit 0fd7524

File tree

1 file changed

+145
-34
lines changed

1 file changed

+145
-34
lines changed

README.md

Lines changed: 145 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# SvelteFire
22

3-
A minimal, yet powerful library that puts realtime Firebase data into Svelte stores.
3+
A minimal, yet powerful library that puts realtime Firebase data into Svelte stores.
44

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

77
```svelte
88
<!-- 1. 🔥 Firebase App -->
9-
<FirebaseApp {auth} {firestore}>
9+
<FirebaseApp {auth} {firestore} {rtdb}>
1010
1111
<!-- 2. 👤 Get the current user -->
1212
<SignedIn let:user>
@@ -15,13 +15,24 @@ A minimal, yet powerful library that puts realtime Firebase data into Svelte sto
1515
1616
<!-- 3. 📜 Get a Firestore document owned by a user -->
1717
<Doc ref={`posts/${user.uid}`} let:data={post} let:ref={postRef}>
18-
18+
1919
<h2>{post.title}</h2>
2020
2121
<!-- 4. 💬 Get all the comments in its subcollection -->
2222
<Collection ref={postRef.path + '/comments'} let:data={comments}>
2323
{#each comments as comment}
2424
25+
{/each}
26+
27+
<!-- 3. 📜 Get a Realtime Database node owned by a user -->
28+
<Node path={`posts/${user.uid}`} let:data={post} let:ref={postRef}>
29+
30+
<h2>{post.title}</h2>
31+
32+
<!-- 4. 💬 Get all the comments in its subnodes -->
33+
<NodeList path={postRef.path + '/comments'} let:data={comments}>
34+
{#each comments as comment}
35+
2536
{/each}
2637
...
2738
```
@@ -30,10 +41,10 @@ A minimal, yet powerful library that puts realtime Firebase data into Svelte sto
3041

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

33-
- Access users and realtime Firestore data as Svelte stores
44+
- Access users, realtime Firestore and Realtime Database data as Svelte stores
3445
- Automatic subscription disposal to prevent memory/cost leaks
3546
- Better TypeScript experience for Firebase
36-
- Handle complex relational data between Auth and Firestore
47+
- Handle complex relational data between Auth, Firestore, and Realtime Database
3748
- Easily hydrate SvelteKit server data into a realtime Firebase stream
3849

3950
## Quick Start
@@ -45,13 +56,15 @@ npm i sveltefire firebase
4556
```
4657

4758
```ts
48-
import { initializeApp } from 'firebase/app';
49-
import { getFirestore } from 'firebase/firestore';
50-
import { getAuth } from 'firebase/auth';
59+
import { initializeApp } from "firebase/app";
60+
import { getFirestore } from "firebase/firestore";
61+
import { getDatabase } from "firebase/database";
62+
import { getAuth } from "firebase/auth";
5163

5264
// Initialize Firebase
5365
const app = initializeApp(/* your firebase config */);
5466
export const db = getFirestore(app);
67+
export const rtdb = getDatabase(app);
5568
export const auth = getAuth(app);
5669
```
5770

@@ -67,9 +80,9 @@ export const auth = getAuth(app);
6780
Hello {$user?.uid}
6881
```
6982

70-
3. Listen to realtime data.
83+
3. Listen to realtime data.
7184

72-
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.
85+
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.
7386

7487
```svelte
7588
<script>
@@ -83,8 +96,7 @@ Use the `$` as much as you want - it will only result in one Firebase read reque
8396
{$post?.title}
8497
```
8598

86-
Or better yet, use the built in `Doc` and `Collection` components. See below.
87-
99+
Or better yet, use the built in `Doc` and `Collection` components for Firestore, or `Node` and `NodeList` components for Realtime Database. See below.
88100

89101
## Stores
90102

@@ -110,15 +122,15 @@ Listen to the current user. Render UI conditionally based on the auth state:
110122

111123
### Firestore Stores
112124

113-
Subscribe to realtime data. The store will unsubscribe automatically to avoid unnecessary Firestore reads.
125+
Subscribe to realtime data. The store will unsubscribe automatically to avoid unnecessary Firestore reads.
114126

115127
```svelte
116128
<script>
117129
import { docStore, collectionStore } from 'sveltefire';
118130
119131
const post = docStore(firestore, 'posts/test');
120132
121-
// OR
133+
// OR
122134
123135
const posts = collectionStore(firestore, 'posts');
124136
</script>
@@ -134,12 +146,46 @@ Cast Firebase data to a TS interface:
134146

135147
```ts
136148
interface Post {
137-
id: string;
138-
title: string;
139-
content: string;
149+
id: string;
150+
title: string;
151+
content: string;
152+
}
153+
const post = docStore<Post>(firestore, "posts/test");
154+
const posts = collectionStore<Post>(firestore, "posts");
155+
```
156+
157+
### Realtime Database Stores
158+
159+
Subscribe to realtime data. The store will unsubscribe automatically to avoid unnecessary Realtime Database reads.
160+
161+
```svelte
162+
<script>
163+
import { nodeStore, nodeListStore } from 'sveltefire';
164+
165+
const post = nodeStore(rtdb, 'posts/test');
166+
167+
// OR
168+
169+
const posts = nodeListStore(rtdb, 'posts');
170+
</script>
171+
172+
{$post?.content}
173+
174+
{#each $posts as post}
175+
176+
{/each}
177+
```
178+
179+
Cast Firebase data to a TS interface:
180+
181+
```ts
182+
interface Post {
183+
id: string;
184+
title: string;
185+
content: string;
140186
}
141-
const post = docStore<Post>(firestore, 'posts/test');
142-
const posts = collectionStore<Post>(firestore, 'posts');
187+
const post = nodeStore<Post>(rtdb, "posts/test");
188+
const posts = nodeListStore<Post>(rtdb, "posts");
143189
```
144190

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

169-
// Just give the store a startWith value
170-
const post = docStore(firestore, 'posts/test', data.post);
215+
// Just give the store a startWith value
216+
const post = docStore(firestore, "posts/test", data.post);
171217
```
172218

173219
## Realtime Components
@@ -176,17 +222,18 @@ In addition to stores, SvelteFire provides a set of components that can build co
176222

177223
### FirebaseApp
178224

179-
The `FirebaseApp` component puts the FirebaseSDK into Svelte context. This avoids the need to pass `auth` and `firestore` down to every component. It is typically placed in root layout.
225+
The `FirebaseApp` component puts the FirebaseSDK into Svelte context. This avoids the need to pass `auth`, `firestore` and `rtdb` down to every component. It is typically placed in root layout.
180226

181227
```svelte
182228
<!-- +layout.svelte -->
183229
<script>
184230
// Initialize Firebase...
185-
const db = getFirestore(app);
231+
const firestore = getFirestore(app);
232+
const rtdb = getDatabase(app);
186233
const auth = getAuth(app);
187234
</script>
188235
189-
<FirebaseApp {auth} {firestore}>
236+
<FirebaseApp {auth} {firestore} {rtdb} >
190237
191238
<User let:user></User>
192239
<!-- other sveltefire components here -->
@@ -199,13 +246,13 @@ You can use Svelte's context API to access the Firebase SDK in any component.
199246
```svelte
200247
<script>
201248
import { getFirebaseContext } from "sveltefire";
202-
const { auth, firestore } = getFirebaseContext();
249+
const { auth, firestore, rtdb } = getFirebaseContext();
203250
</script>
204251
```
205252

206253
### User
207254

208-
Get the current user.
255+
Get the current user.
209256

210257
```svelte
211258
<SignedIn let:user>
@@ -238,7 +285,7 @@ Slot props can be renamed:
238285
```
239286

240287
Firestore components can also handle loading states:
241-
288+
242289
```svelte
243290
<Doc path="posts/test">
244291
<!-- data renders here in the default slot -->
@@ -252,10 +299,9 @@ Pass a `startWith` value to bypass the loading state. This is useful in SvelteKi
252299
<Doc ref="posts/test" startWith={dataFromServer}>
253300
```
254301

255-
256302
### Collection
257303

258-
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.
304+
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.
259305

260306
```svelte
261307
<Collection ref="posts" let:data let:count>
@@ -279,22 +325,71 @@ Collections can also take a Firestore Query instead of a path:
279325
</Collection>
280326
```
281327

328+
### Node
329+
330+
Fetch a single node from the Realtime Database and listen to its data in realtime. The `data` slot prop gives you access to the fetched data, and the `ref` provides the Realtime Database reference.
331+
332+
```svelte
333+
<Node path="posts/test" let:data let:ref>
334+
{data.content}
335+
{ref.key}
336+
</Node>
337+
```
338+
339+
Slot props can be renamed:
340+
341+
```svelte
342+
<Node path="posts/test" let:data={post} let:ref={postRef}>
343+
{post.content}
344+
{postRef.key}
345+
</Node>
346+
```
347+
348+
Realtime Database components can also handle loading states:
349+
350+
```svelte
351+
<Node path="posts/test">
352+
<!-- data renders here in the default slot -->
353+
<div slot="loading">Loading.... This will disappear when data is defined</div>
354+
</Node>
355+
```
356+
357+
Pass a `startWith` value to bypass the loading state. This is useful in SvelteKit when you need to hydrate server data into a realtime stream:
358+
359+
```svelte
360+
<Node path="posts/test" startWith={dataFromServer}>
361+
```
362+
363+
### NodeList
364+
365+
Fetch lists of nodes from the Realtime Database and listen to their data in realtime. The component provides an array of the data with the `data` slot prop, the reference with `ref`, and the `count` of items in the list with count.
366+
367+
```svelte
368+
<NodeList path="posts" let:data let:count>
369+
<p>Fetched {count} posts</p>
370+
{#each data as post}
371+
{item.nodeKey}
372+
{post.content}
373+
{/each}
374+
</NodeList>
375+
```
376+
282377
### Using Components Together
283378

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

286-
287381
```svelte
288382
<FirebaseApp {auth} {firestore}>
289383
<SignedIn let:user>
290384
<p>UID: {user.uid}</p>
291-
385+
292386
<h3>Profile</h3>
387+
388+
<!-- 📜 Fetch data using Firestore -->
293389
<Doc ref={`posts/${user.uid}`} let:data={profile} let:ref={profileRef}>
294390
295391
{profile.content}
296392
297-
298393
<h4>Comments</h4>
299394
<Collection ref={profileRef.path + '/comments'} let:data={comments}>
300395
{#each comments as comment}
@@ -306,6 +401,23 @@ These components can be combined to build complex realtime apps. It's especially
306401
307402
<div slot="loading">Loading Profile...</div>
308403
</Doc>
404+
405+
<!-- 📜 Fetch data using Realtime Database -->
406+
<Node path={`posts/${user.uid}`} let:data={profile} let:ref={profileRef}>
407+
408+
{profile.content}
409+
410+
<h4>Comments</h4>
411+
<NodeList path={profileRef.path + '/comments'} let:data={comments}>
412+
{#each comments as comment}
413+
<strong>{comment.content}</strong>
414+
{/each}
415+
416+
<div slot="loading">Loading Comments...</div>
417+
</NodeList>
418+
419+
<div slot="loading">Loading Profile...</div>
420+
</Node>
309421
</SignedIn>
310422
311423
<SignedOut>
@@ -314,10 +426,9 @@ These components can be combined to build complex realtime apps. It's especially
314426
</FirebaseApp>
315427
```
316428

317-
318429
## Roadmap
319430

320431
- Add support for Firebase Storage
321-
- Add support for Firebase RTDB
432+
- ~~Add support for Firebase RTDB~~ (Added in latest release!)
322433
- Add support for Firebase Analytics in SvelteKit
323434
- Find a way to make TS generics with with Doc/Collection components

0 commit comments

Comments
 (0)