I am working on a project in react native with a firestore database. I have stored articles with a timestamp that I want to filter when i fetch the data from the database.
const getLoads = async (e) => {
const today = getCurrentSeconds();
console.log(today);
await getDocs(collection(db, 'load'))
.then((QuerySnapshot) => {
const newData = QuerySnapshot.docs
.filter((item) => item.date >= today)
.map((doc) => ({...doc.data(), id:doc.id }));
setLoad(newData);
console.log(load, newData);
});
setIsLoading(false);
}
As getCurrentSeconds()
returns seconds and the firestore timestamp is in the format of seconds and nanoseconds.
I’m guessing that the comparison won’t do anything as they’re in nanoseconds as well and I haven’t found a good way to acquire this. What I want to do is just compare the seconds.
How do I make the comparison correctly?
This is what the date from the firebase looks like:
date: it {seconds: 1684748618, nanoseconds: 863000000}
I tried calling a function that returns todays date and then compare that to the timestamp I get from firestore:
The function that is supposed to return todays date:
/*
* Returns todays date
*/
export const getCurrentDate=() => {
var date = new Date().getDate();
var month = new Date().getMonth() + 1;
var year = new Date().getFullYear();
return date + '/' + month;
}
export const getCurrentSeconds=() => {
var now = Date.now();
return now;
}
the getCurrentSeconds()
returns 1684829176108.
the timestamp from the firestore is: 1684748618 which is three digits shorter than the getCurrentSeconds()
.
2
Answers
You probably could try this method…assuming that the "date" field in your Firestore documents is also a timestamp in seconds, you can modify your filter condition to correctly compare the values. Here’s an updated version of your code:
In the updated code, the
filter()
function is used to check if the"date.seconds"
property of each document is greater than or equal to the current timestamp inseconds (today)
. By accessing the"seconds"
property of the Firestore timestamp, you ensure that you are comparing the correct values.To begin with,
Date.now()
returns the number of milliseconds since the epoch. This means that your currentgetCurrentSeconds()
method is returning milliseconds instead of seconds.Next,
QuerySnapshot.docs
is an array ofQueryDocumentSnapshot
objects. These objects do not have adate
property, soitem.date
in your callback will always returnundefined
. This effectively makes your callback.filter(item => undefined > today)
which will return false in all cases. To correctly extract thedate
field from your document, you need to useitem.get("date")
oritem.data().date
in your callback.Next we need to address the logic error in your function where you set
today
to the current number of seconds since the epoch. This will mean that unless your database contains data for dates in the future, it will always return no results. If you instead want to get all the data since midnight today, you need to introduce agetTodayMidnightSeconds()
function.However, the above steps can be simplified by querying using the desired
Date
object instead of applying a filter client-side. This will also improve speed and reduce costs.Lastly, you should move the
setLoad
andsetIsLoading
calls outside of the getLoads call and move the getLoads function out of your component if you are calling it from inside auseEffect
call.You can also reduce some of this boilerplate using
useAsyncEffect
from@react-hook/async
oruse-async-effect
depending on your style. The former will handle the loading state for you.