Skip to content

Commit ebe9a0a

Browse files
committed
fix: address ssr edge cases and rm context api
1 parent 7c1ad2e commit ebe9a0a

9 files changed

+66
-40
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

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

5+
Experimental! Do not use in production.
6+
57
```svelte
68
<!-- 1. 🔥 Firebase App -->
79
<FirebaseApp {auth} {firestore}>
@@ -301,3 +303,4 @@ These components can be combined to build complex realtime apps. It's especially
301303
- This library should only run the the client, it is not for server-side data fetching.
302304
- Requires Firebase v9 or greater.
303305
- I've have not been able to get TS generics to work right in the components yet, so no intellisense on the `data` slot prop.
306+
- How should we bundle it properly?

package.json

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sveltefire",
3-
"version": "0.2.1",
3+
"version": "0.2.3",
44
"scripts": {
55
"dev": "vite dev",
66
"build": "svelte-kit sync && svelte-package",
@@ -20,10 +20,8 @@
2020
"tslib": "^2.4.1",
2121
"typescript": "^4.9.3",
2222
"vite": "^4.0.0",
23-
"vitest": "^0.25.3"
24-
},
25-
"type": "module",
26-
"dependencies": {
23+
"vitest": "^0.25.3",
2724
"firebase": "^9.15.0"
28-
}
25+
},
26+
"type": "module"
2927
}

src/lib/Collection.svelte

+3-6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
Firestore,
55
Query,
66
} from 'firebase/firestore';
7-
import { getContext } from 'svelte';
8-
import { collectionStore, key } from './stores';
7+
import { collectionStore, sdk } from './stores';
98
109
// TODO figure out how to make generics work
1110
// current setup will not work without mandatory startWith value
@@ -16,14 +15,12 @@
1615
// }
1716
1817
interface $$Slots {
19-
default: { data: any[]; ref: CollectionReference | Query; count: number },
18+
default: { data: any[]; ref: CollectionReference | Query | null; count: number },
2019
loading: {},
2120
}
2221
23-
const config = getContext<any>(key);
24-
2522
export let ref: string | CollectionReference | Query;
26-
export let firestore: Firestore = config.getFirestore();
23+
export let firestore: Firestore = $sdk?.firestore;
2724
export let startWith: any = undefined;
2825
2926
let store = collectionStore(firestore, ref, startWith);

src/lib/Doc.svelte

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
22
import type { DocumentReference, Firestore } from 'firebase/firestore';
3-
import { getContext } from 'svelte';
4-
import { docStore, key } from './stores';
3+
import { docStore, sdk } from './stores';
54
65
// TODO figure out how to make generics work
76
// code below will not work without mandatory startWith value
@@ -13,14 +12,12 @@
1312
// }
1413
1514
interface $$Slots {
16-
default: { data: any; ref: DocumentReference },
15+
default: { data: any; ref: DocumentReference | null },
1716
loading: {},
1817
}
1918
20-
const config = getContext<any>(key);
21-
2219
export let ref: string | DocumentReference;
23-
export let firestore: Firestore = config?.getFirestore();
20+
export let firestore: Firestore = $sdk?.firestore;
2421
export let startWith: any = undefined;
2522
2623
let store = docStore(firestore, ref, startWith);

src/lib/FirebaseApp.svelte

+4-13
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
11
<script lang="ts">
22
import type { Auth } from 'firebase/auth';
33
import type { Firestore } from 'firebase/firestore';
4-
import { onDestroy, setContext } from 'svelte';
5-
import { key } from './stores';
4+
import { sdk } from './stores';
65
76
export let firestore: Firestore;
87
export let auth: Auth;
9-
10-
setContext(key, {
11-
getFirestore: () => firestore,
12-
getAuth: () => auth,
13-
});
14-
15-
onDestroy(() => {
16-
setContext(key, null);
17-
});
18-
8+
sdk.set({ firestore, auth });
199
</script>
2010

21-
<slot />
11+
12+
<slot />

src/lib/User.svelte

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<script lang="ts">
22
import type { Auth, User } from "firebase/auth";
3-
import { getContext } from "svelte";
4-
import { key, userStore } from "./stores";
3+
import { sdk, userStore } from "./stores";
54
65
interface $$Slots {
76
default: { user: User }
87
signedOut: {}
98
}
10-
const config = getContext<any>(key);
11-
export let auth: Auth = config?.getAuth();
9+
10+
export let auth: Auth = $sdk?.auth;
1211
1312
const user = userStore(auth);
1413
</script>

src/lib/stores.ts

+32-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ export function docStore<T>(
2121
) {
2222
let unsubscribe: () => void;
2323

24+
// Fallback for SSR
25+
if (!firestore || !globalThis.window) {
26+
console.warn('Firestore is not initialized or not in browser');
27+
const { subscribe } = writable(startWith);
28+
return {
29+
subscribe,
30+
ref: null,
31+
id: '',
32+
}
33+
}
34+
2435
const docRef = typeof ref === 'string' ? doc(firestore, ref) : ref;
2536

2637
const { subscribe } = writable<T | null>(startWith, (set) => {
@@ -51,6 +62,16 @@ export function collectionStore<T>(
5162
) {
5263
let unsubscribe: () => void;
5364

65+
// Fallback for SSR
66+
if (!firestore || !globalThis.window) {
67+
console.warn('Firestore is not initialized or not in browser');
68+
const { subscribe } = writable(startWith);
69+
return {
70+
subscribe,
71+
ref: null,
72+
}
73+
}
74+
5475
const colRef = typeof ref === 'string' ? collection(firestore, ref) : ref;
5576

5677
const { subscribe } = writable(startWith, (set) => {
@@ -76,7 +97,15 @@ export function collectionStore<T>(
7697
export function userStore(auth: Auth) {
7798
let unsubscribe: () => void;
7899

79-
const { subscribe } = writable(auth.currentUser, (set) => {
100+
if (!auth || !globalThis.window) {
101+
console.warn('Auth is not initialized on not in browser');
102+
const { subscribe } = writable(null);
103+
return {
104+
subscribe,
105+
}
106+
}
107+
108+
const { subscribe } = writable(auth?.currentUser ?? null, (set) => {
80109
unsubscribe = onAuthStateChanged(auth, (user) => {
81110
set(user);
82111
});
@@ -89,5 +118,5 @@ export function userStore(auth: Auth) {
89118
};
90119
}
91120

92-
// Key for context
93-
export const key = Symbol();
121+
// SDK store for FirebaseApp comopnent
122+
export const sdk = writable<{ auth: Auth; firestore: Firestore }>();

src/routes/+page.svelte

+8-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727

2828
<FirebaseApp {auth} {firestore}>
2929

30+
<Doc ref="posts/test" startWith={{ content: 'sup'}} let:data={post}>
31+
<p>{post.content}</p>
32+
<div slot="loading">
33+
<p>Loading...</p>
34+
</div>
35+
</Doc>
36+
3037
<User let:user>
3138

3239
<p>Hello {user?.uid}</p>
@@ -40,7 +47,7 @@
4047

4148
<h1>Your Posts</h1>
4249

43-
<Collection ref={makeQuery(user.uid)} let:data={posts} let:count>
50+
<Collection ref={makeQuery(user.uid)} startWith={[]} let:data={posts} let:count>
4451

4552
<p>You've made {count} posts</p>
4653

src/routes/firebase.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import { getAuth } from "firebase/auth";
44

55

66
const firebaseConfig = {
7-
7+
apiKey: "AIzaSyBOL3Y80Y6JASfwgvyq8IL6FlnrBQBN_0E",
8+
authDomain: "testing-proj-b7c60.firebaseapp.com",
9+
projectId: "testing-proj-b7c60",
10+
storageBucket: "testing-proj-b7c60.appspot.com",
11+
messagingSenderId: "665240273060",
12+
appId: "1:665240273060:web:b81550e114a46af9116631"
813
};
914

1015
// Initialize Firebase

0 commit comments

Comments
 (0)