Skip to content

Instantly share code, notes, and snippets.

@rohailtaha
Created August 11, 2023 09:49
Show Gist options
  • Save rohailtaha/c66265c886b87bff173f41b1f62eaf6b to your computer and use it in GitHub Desktop.
Save rohailtaha/c66265c886b87bff173f41b1f62eaf6b to your computer and use it in GitHub Desktop.
Firestore Reusable Methods
// max operations that can be performed in a batch
export const MAX_BATCH_SIZE = 500
export async function addDoc(collectionRef: string, data: Record<any, any>) {
const database = getFirestoreDatabase()
return await addDocFirebase(collection(database, collectionRef), data)
}
export async function setDoc(docRef: string, data: Record<any, any>) {
const database = getFirestoreDatabase()
return await setDocFirebase(doc(database, docRef), data)
}
export async function getDoc(
docRef: string,
// eslint-disable-next-line no-unused-vars
converter?: (docSnapshot: QueryDocumentSnapshot<DocumentData>) => any
) {
const database = getFirestoreDatabase()
let firebaseDocRef = doc(database, docRef)
if (converter) {
var firebaseConverter: FirestoreDataConverter<any> = {
fromFirestore: snapshot => {
return converter(snapshot)
},
toFirestore: () => ({})
}
firebaseDocRef = firebaseDocRef.withConverter(firebaseConverter)
}
const docSnapshot = await getDocFirebase(firebaseDocRef)
if (docSnapshot.exists()) {
return docSnapshot.data()
}
}
export async function deleteDoc(docRef: string) {
const database = getFirestoreDatabase()
return await deleteDocFirebase(doc(database, docRef))
}
export async function updateDoc(docRef: string, data: Record<any, any>) {
const database = getFirestoreDatabase()
return await updateDocFirebase(doc(database, docRef), data)
}
export async function getCollection(
collectionRef: string,
converter?: (
// eslint-disable-next-line no-unused-vars
docSnapshot: QueryDocumentSnapshot<DocumentData>
) => Record<any, any>
) {
const database = getFirestoreDatabase()
const dataSnapshot = await getDocsFirebase(
collection(database, collectionRef)
)
const converterFunction = converter
? converter
: (docSnapshot: QueryDocumentSnapshot<DocumentData>) =>
docSnapshot.data()
return dataSnapshot.docs.map(converterFunction)
}
export function getFirestoreDatabase() {
return getFirestore(app)
}
export function getWriteBatch() {
return writeBatch(getFirestoreDatabase())
}
export function getDocRef(docPath: string) {
return doc(getFirestoreDatabase(), docPath)
}
type BatchOperation = "set" | "update" | "delete"
export async function commitBatch<T = any>({
items,
docPath,
operation,
data
}: {
items: Array<T>
// eslint-disable-next-line no-unused-vars
docPath: ((item: T) => string) | string
// eslint-disable-next-line no-unused-vars
operation: ((item: T) => BatchOperation) | BatchOperation
data?: Record<any, any>
}) {
const batchPromises = []
const database = getFirestoreDatabase()
let batch = getWriteBatch()
for (let i = 0; i < items.length; i++) {
// Get a document reference
const $docPath =
typeof docPath === "string" ? docPath : docPath(items[i])
const $operation =
typeof operation === "string" ? operation : operation(items[i])
// Add the operation to the batch
if ($operation === "set") {
batch.set(doc(database, $docPath), data)
} else if ($operation === "update") {
batch.update(doc(database, $docPath), data)
} else if ($operation === "delete") {
batch.delete(doc(database, $docPath))
}
// Check if the chunk for batch is complete. Max chunk size is 500
// (max number of operations in a batch)
if ((i + 1) % MAX_BATCH_SIZE === 0 || i === items.length - 1) {
// Commit the batch
batchPromises.push(batch.commit())
// Get a new write batch for the next chunk
batch = getWriteBatch()
}
}
return await Promise.all(batchPromises)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment