Good Day,
Please help me figure out how to filter the firestore query to show only the data from today's date.
Here is my React code:
`
const History = () => {
const [codeexplainer, setExamples] = useState([]);
const [user] = useAuthState(auth);
const uid = user ? user.uid : "null";
useEffect(() => {
const fetchData = async () => {
const response = await fetch("/api/code/firebase-config");
const data = await response.json();
setExamples(data);
};
fetchData();
}, []);
const filteredData = useMemo(() => {
if (uid) {
return codeexplainer
.filter((result) => result.uid === uid && result !== undefined)
.sort((a, b) => b.timestamp - a.timestamp)
// .slice(0, 10);
}
return undefined;
}, [codeexplainer, uid])
const datafromfirebase = useMemo(() => {
if (filteredData && filteredData.length > 0) {
return filteredData.map((result) => (
<>
<Examples
code={result.code}
result={result.explanation}
/>
</>
))
} else {
return <p>Hey there! Add some code snippets and come back to see your history here.</p>
}
}, [filteredData])
`
Sample Firestore Data
This is the Firebase Config I am currently using.
Firebase Config:
import { initializeApp } from "firebase/app";
import { getFirestore } from "@firebase/firestore";
import {
collection,
addDoc,
getDocs,
serverTimestamp,
} from "firebase/firestore";
export const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
const resultsCollectionRef = collection(db, "codeexplainer");
const profaneCollectionRef = collection(db, "swear");
export default async function firebaseGet(req, res) {
if (req.method === "GET") {
const data = await getDocs(resultsCollectionRef);
const response = data.docs.map((doc) => ({ ...doc.data(), id: doc.id }));
res.status(200).json(response);
}
}
export async function createFirebaseData(code, user, choices, userid) {
await addDoc(resultsCollectionRef, {
code: code,
user: user,
explanation: choices,
timestamp: serverTimestamp(),
uid: userid,
});
}
export async function getFirebaseData(req, res) {
const data = await getDocs(resultsCollectionRef);
const response = data.docs.map((doc) => ({ ...doc.data(), id: doc.id }));
return response;
}
export async function loggedProfane(code, user, userid) {
await addDoc(profaneCollectionRef, {
code: code,
timestamp: serverTimestamp(),
user: user,
uid: userid,
});
}
Thank you.
I have tried the sorting and slice method but it's not working.
I'm new to React.
CodePudding user response:
You are essentially fetching all the documents and the filtering them on the client side. If a user is supposed to read/write their documents only then this is not secure as anyone can read documents of all users and also inefficient as you are loading all the documents everytime just to show a subset. Instead you should use a query and security rules so a user can read their own data only. Try using this query:
import { query, collection, getDocs, where } from "firebase/firestore"
const startOfToday = new Date();
startOfToday.setUTCHours(0,0,0,0);
// Documents created today (after 00:00 UTC)
const q = query(resultsCollectionRef, where("timestamp", ">", startOfToday));
const data = await getDocs(resultsCollectionRef);
const response = data.docs.map((doc) => ({ ...doc.data(), id: doc.id }));
You don't need any filtering or sorting on client side and can simply map the data into UI.