manifold/web/lib/firebase/utils.ts
Marshall Polaris 3b4666ba3e
Add Firebase schema collection helpers (kind of an RFC) (#583)
* Add Firebase schema collection helpers

* Decentralize definitions from schema file (James feedback)

* Add lint comment
2022-06-29 12:21:40 -07:00

53 lines
1.5 KiB
TypeScript

import {
collection,
getDoc,
getDocs,
onSnapshot,
Query,
CollectionReference,
DocumentReference,
} from 'firebase/firestore'
import { db } from './init'
export const coll = <T>(path: string, ...rest: string[]) => {
return collection(db, path, ...rest) as CollectionReference<T>
}
export const getValue = async <T>(doc: DocumentReference) => {
const snap = await getDoc(doc)
return snap.exists() ? (snap.data() as T) : null
}
export const getValues = async <T>(query: Query) => {
const snap = await getDocs(query)
return snap.docs.map((doc) => doc.data() as T)
}
export function listenForValue<T>(
docRef: DocumentReference,
setValue: (value: T | null) => void
) {
// Exclude cached snapshots so we only trigger on fresh data.
// includeMetadataChanges ensures listener is called even when server data is the same as cached data.
return onSnapshot(docRef, { includeMetadataChanges: true }, (snapshot) => {
if (snapshot.metadata.fromCache) return
const value = snapshot.exists() ? (snapshot.data() as T) : null
setValue(value)
})
}
export function listenForValues<T>(
query: Query,
setValues: (values: T[]) => void
) {
// Exclude cached snapshots so we only trigger on fresh data.
// includeMetadataChanges ensures listener is called even when server data is the same as cached data.
return onSnapshot(query, { includeMetadataChanges: true }, (snapshot) => {
if (snapshot.metadata.fromCache) return
const values = snapshot.docs.map((doc) => doc.data() as T)
setValues(values)
})
}