Skip to content

Instantly share code, notes, and snippets.

@mikevb3
Created September 28, 2021 12:05
Show Gist options
  • Save mikevb3/3cda830d39a631a0e233c72716be3a3a to your computer and use it in GitHub Desktop.
Save mikevb3/3cda830d39a631a0e233c72716be3a3a to your computer and use it in GitHub Desktop.
React hook for using Firestore SDK Version 9.
import { WhereFilterOp } from "firebase/firestore";
export interface IQuery {
ref: string;
operator: WhereFilterOp;
value: any;
}
import { useState } from "react";
import { fs } from "../config/firebase"; // const fs = useFirestore() from the initializeApp config
import { collection, query, where, getDocs, limit } from "firebase/firestore";
import useInterval from "./useInterval";
import { IQuery } from "../types/Firestore";
const useFirestore = (
collectionString: string = "defaultCollection",
limitNumber: number = 100,
queryData?: IQuery
) => {
const [data, setData] = useState<any[] | void>([]);
// Instead of using the snapshot directly, im throttling the data updating to a second.
useInterval(async () => {
const result = await querySnapshot;
setData(result);
}, 1000);
// Create a query against the collection.
const q = queryData
? query(
collection(fs, collectionString),
where(queryData?.ref, queryData?.operator, queryData?.value),
limit(limitNumber)
)
: query(collection(fs, collectionString), limit(limitNumber));
const querySnapshot = getDocs(q)
.then((snapshot) => {
const data: any[] = snapshot.docs.map((doc) => {
return {
id: doc.id,
...doc.data(),
};
});
return data;
})
.catch((error) => {
console.error("Error getting documents: ", error);
});
return { data };
};
export default useFirestore;
// Original from 'https://usehooks-typescript.com/react-hook/use-interval'
import { useEffect, useRef } from "react";
function useInterval(callback: () => void, delay: number | null) {
const savedCallback = useRef(callback);
// Remember the latest callback if it changes.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
// Don't schedule if no delay is specified.
if (delay === null) {
return;
}
const id = setInterval(() => savedCallback.current(), delay);
return () => clearInterval(id);
}, [delay]);
}
export default useInterval;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment