Created
September 8, 2023 04:05
-
-
Save metruzanca/93191eddf7812a0642b12688bef363cf to your computer and use it in GitHub Desktop.
Inspired by https://github.com/codediodeio/sveltefire & previous stuff I did here https://gist.github.com/metruzanca/e516aac42c79d16c894883e88d8af5f8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Inspired by https://github.com/codediodeio/sveltefire & previous stuff I did here https://gist.github.com/metruzanca/e516aac42c79d16c894883e88d8af5f8 | |
import { CollectionReference, DocumentData, Firestore, Query, QueryDocumentSnapshot, QuerySnapshot, collection, onSnapshot } from "firebase/firestore"; | |
import { Accessor, from } from "solid-js"; | |
type CollectionSignal<T> = { | |
signal: Accessor<T[]> | |
ref: CollectionReference<T> | Query<T> | null | |
} | |
export function createCollectionSignal<T>( | |
firestore: Firestore, | |
ref: string | Query<T, DocumentData> | CollectionReference<T, DocumentData>, | |
startWith: T[] = [] | |
): CollectionSignal<T> { | |
let unsubscribe: () => void; | |
// TODO firebase-admin | |
// // Fallback for SSR | |
// if (!globalThis.window) { | |
// const { subscribe } = writable(startWith); | |
// return { | |
// subscribe, | |
// ref: null, | |
// }; | |
// } | |
// Fallback for missing SDK | |
if (!firestore) { | |
console.warn( | |
"Firestore is not initialized. Are you missing FirebaseApp as a parent component?" | |
); | |
const signal = () => [] | |
return { | |
signal, | |
ref: null, | |
} | |
} | |
const collectionRef = typeof ref === "string" ? collection(firestore, ref) : ref as CollectionReference; | |
const signal = from<T[]>(set => { | |
set(startWith) | |
unsubscribe = onSnapshot(collectionRef, (snapshot: QuerySnapshot) => { | |
const data = snapshot.docs.map((doc: QueryDocumentSnapshot) => { | |
return { id: doc.id, ref: doc.ref, ...doc.data() } as T; | |
}); | |
set(data); | |
}); | |
return () => unsubscribe(); | |
}) | |
return { | |
signal: signal as Accessor<T[]>, | |
ref: collectionRef as CollectionReference<T>, | |
}; | |
} | |
// Example proxy to avoid having to import firestore everywhere | |
// export const proxyCreateCollectionSignal = <T>( | |
// ref: string | Query<T, DocumentData> | CollectionReference<T, DocumentData>, | |
// startWith: T[] | |
// ) => createCollectionSignal<T>(firestore, ref, startWith) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment