Skip to content

Instantly share code, notes, and snippets.

@metruzanca
Created September 8, 2023 04:05
Show Gist options
  • Save metruzanca/93191eddf7812a0642b12688bef363cf to your computer and use it in GitHub Desktop.
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
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