I need the help to query long collection with date range. See the below example document. I wanna query startTime field using date range.

- 565,676
- 79
- 828
- 807

- 1,494
- 2
- 7
- 8
-
All these answers have a huge flaw: A query can only contain ">" or "<" one one field. This means that using this approach for filtering date, will then make it impossible to filter on ranges on other fields. – Spock Jul 05 '21 at 19:37
13 Answers
Since I have the dueDate
field stored as "timestamp" (and NOT as string or number) on Cloud Firestore, I did this to get the invoice documents with a due date on 2017:
let start = new Date('2017-01-01');
let end = new Date('2018-01-01');
this.afs.collection('invoices', ref => ref
.where('dueDate', '>', start)
.where('dueDate', '<', end)
);
NOTE: dueDate
field was stored at firebase with a Date() object. e.g.: this.doc.dueDate = new Date('2017-12-25')

- 5,167
- 2
- 20
- 21
-
1If you take a screenshot of your firestore, is it possible from there to visually tell the difference between a datetime object or string? – DauleDK Oct 30 '17 at 07:25
-
Yes @DauleDK look: https://imgur.com/a/draQo the third field was filled with a Date() js object and it was stored as a timestamp (firebase made the convertion). And on the image you will see this timestamp formatted as UTC BUT I saved it as a Date object. And finally to check if this is really a timestamp field just hover the field. In my case I see "Marca de tiempo" which means "timestamp". – Capy Oct 30 '17 at 10:34
-
3Wow that is awesome - something that should definitely be added to the firestore query documentation. I have this feeling that we will see many updates to the firebase-firestore console. "Marce de tiempo" - most valuable lesson learned today, gracias ;) – DauleDK Oct 30 '17 at 10:53
-
4
-
Also, if you are using an additional equivalence query '==', you may need to enable a composite index, the best way to do this is by catching the error, which will output a Firebase link that you can follow to auto-setup the index. My request looks like this and needed a composite_index: ```.where('team_id', '==', teamId).where('time', '>=', start).where('time', '<=', end)``` – widavies Apr 13 '20 at 00:32
You could store the datetime object as Unix time (seconds since 1 January 1970). Then you can simple use the where select like this:
collectionRef.where("startTime", ">=", "1506816000").where("startTime", "<=", "1507593600")
Btw - to convert from datetime to Unix time in your app, you can use the excellent (now deprecated) library moment (if you are building something with js or node).
-
1thanks , but i have already data with date format just like the attached screenshot – Nimer Farahty Oct 30 '17 at 06:15
-
Ok. According to firebase datetime is a supported data type in firestore. Is the startTime a string or datetime object? – DauleDK Oct 30 '17 at 06:25
-
-
can you take a screenshot from the firebase console - where you hover the mouse above your startTime - to see if datetime appear like here https://imgur.com/a/draQo – DauleDK Oct 30 '17 at 17:07
-
added to question new screenshot , it seems the data time is timestamp when i create the field using moment module – Nimer Farahty Oct 30 '17 at 18:27
-
Hi @NimerFarahty - I just tried Capys answer on my own code with `new Date('2017-01-01')` and it seems to work great. Do you get any errors? – DauleDK Nov 06 '17 at 18:28
-
yes it is works , the problem is related to react-native-module and seems that it is currently solved after upgrade to new version, appreciate your help thx @Capy – Nimer Farahty Nov 07 '17 at 22:30
-
var startfulldate = admin.firestore.Timestamp.fromDate(new Date(1556062581000));
db.collection('mycollection')
.where('start_time', '<=', startfulldate)
.get()
.then(snapshot => {
var jsonvalue: any[] = [];
snapshot.forEach(docs => {
jsonvalue.push(docs.data())
})
res.send(jsonvalue);
return;
}).catch( error => {
res.status(500).send(error)
});

- 7,102
- 6
- 26
- 48

- 329
- 3
- 2
-
2Great ! You saved my life man. I just replaced admin.firestore by firebase.firestore and it worked. – Fox5150 Jan 22 '20 at 10:05
-
1This helped me immensely. I can't believe there's no documentation on Firebase for including dates in queries... – bdrelling Oct 30 '21 at 18:27
const event = new Date();
const expirationDate = admin.firestore.Timestamp.fromDate(event);
const query = collectionRef.where('startTime', '<=', expirationDate)

- 2,903
- 1
- 16
- 20
As startTime
stored as Timestamp
, you can do this query range for more accururate (this good for both condition of long date range or same date range).
const start = new Date('2021-01-01T00:00:00.000z');
const end = new Date('2021-03-01T23:59:59.000z');
db.collection('Data').where('startTime', '>=', start).where('startTime', '<=', end).get().then(data => {
//pass your 'data' here
});
I used this in my Node.js apps. Hopefully this useful.

- 239
- 3
- 3
For everyone recently using Firebase Firestore, there's a difference depending on your settings of your Firebase implementation (depending on the firebase version).
Before, Firestore was saving Timestamp
as a Date
, however as described here in the docs the will be replaced soon by a Timestamp
object. See the Timestamp docs here.
You can force your implementation already by adding a setting in your code to force Firebase to use Timestamp objects instead of Date like this example:
var firebaseApp = firebase.initializeApp({
apiKey: [APIKEY],
authDomain: [FIREBASEAPPDOMAIN],
projectId: [PROJECTID]
});
var firestore = firebase.firestore();
var settings = { timestampsInSnapshots: true }; // force Timestamp instead of Date
firestore.settings(settings);
-
1This is actually deprecated and will be removed in a future release. Firebase wants you to specify Timestamp objects specifically, going forward. – ptent May 10 '21 at 17:07
The solution is to use Date.now(). Stop using timestamp service from Firebase, you need to work with the numerical value of the time in milliseconds like for example: 1514271367000, instead if Firestore uses 26/12/2017 1:56:07 GMT- 0500 (-05) will not work. An example of a query is:
this.fsService.afs.collection('chats/4bY1ZpOr1TPq8bFQ3bjS/finance/123+finance/12345'
, ref => ref.orderBy('hour').startAt(1514184967000).endAt(1514271367000))
.valueChanges().subscribe(data =>{
this.mensajes = data;
})

- 2,017
- 1
- 21
- 30

- 75
- 1
- 1
-
2Is it okay if Firestore saves Date.now() as number data? I feel like having date is better in some cases just because of that and easiness of understanding. – Telion Jan 16 '18 at 12:21
-
1This appears to be Firebase Realtime Database code (e.g. it uses `startAt` and `endAt`) not Firestore code (which would use `where`, see [here](https://firebase.google.com/docs/firestore/query-data/order-limit-data)). The two are similar, but not the same. – robsiemb Nov 07 '19 at 17:46
-
1What is the timezone thought. When I determine the number, should I convert the datetime to GMT? – Csaba Toth May 18 '20 at 05:42
Those who, like me, are using PHP to access Firestore, can do something like this:
$startTime = new DateTime('2020-05-23 00:00:00');
$endTime = new DateTime('2020-06-23 23:59:59');
$start = new Google\Cloud\Core\Timestamp($startTime);
$end = new Google\Cloud\Core\Timestamp($endTime);
// fb is a Google\Cloud\Firestore\FirestoreClient object
$this->query = $this->fb->collection('your_collection');
$aux = $this->query;
$aux = $aux->where('startTime', '<', $end);
$aux = $aux->where('startTime', '>', $start);
return $aux->documents();
Enjoy.

- 1,401
- 14
- 20
Generic function to find documents in a collection by date range of specifics fields:
public List<QueryDocumentSnapshot> findDocsByDateRange(
String collection,
String fieldStartDate,
String fieldEndDate,
Date startDate,
Date endDate) {
ApiFuture<QuerySnapshot> querySnapshot = fireStore()
.collection(collection)
.whereGreaterThanOrEqualTo(FieldPath.of(fieldStartDate), startDate)
.whereLessThanOrEqualTo(FieldPath.of(fieldEndDate), endDate)
.get();
return querySnapshot.get().getDocuments();
}
Packages:
import com.google.api.core.ApiFuture;
import com.google.cloud.firestore.DocumentSnapshot;
import com.google.cloud.firestore.FieldPath;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.QueryDocumentSnapshot;
import com.google.cloud.firestore.QuerySnapshot;

- 4,983
- 4
- 38
- 58
In a frontend application, this is how Firebase timestamps and dates can be used to query and store documents.

- 1,528
- 2
- 17
- 44

- 17
- 1
-
4Hello. As much as external links may be useful, please insert the content of your answer directly into SO. – Maciej Jureczko Apr 10 '19 at 07:44
I think this will help you out,
yourMethod() {
var date = DateTime.now();//
print("First Date > " + DateTime(date.year, date.month, 1).toString());
var datex = new DateTime(date.year, date.month + 1, 0);
print("Last Date > " +datex);//
//
Firestore.instance
.collection('biling')
.where("driverId", isEqualTo: widget.uid)
.where("date",
isGreaterThanOrEqualTo:
new DateTime(date.year, date.month, 1).toString())//1
.where("date", isLessThanOrEqualTo: datex.toString())//2
.orderBy('date', descending: true)
.getDocuments()
.then(
(QuerySnapshot snapshot) => {
snapshot.documents.forEach((f) {
if (this.mounted) {
setState(() {
totalP += double.tryParse(f.data["price"]);
});
}
print("_price " + f.data["price"]);
print("_duePaymntForCompay " + f.data["duePaymntForCompay"]);
}),
},
);
}

- 2,348
- 17
- 16
now you need to use these queries for filtering documents with conditions because .where() is not working for me
db.collection("id").whereGreaterThan("field","value")
.whereEqualTo("field","value")
.whereLessThen("field","value")

- 140
- 1
- 8
What worked for me was Format Date with Moment JS and split into Day, Month & Year
const currentDate = moment().format("DD-MM-YYYY").split("-");
const currentDay = currentDate[0];
const currentMonth = currentDate[1];
const currentYear = currentDate[2];
const allDocuments = await collectionRef
.doc(docId)
.collection(*COLLECTION NAME*)
.where(
*DATE PARAMETER NAME*,
">=",
new Date(`${currentYear}-${currentMonth}-${currentDay}`)
)
.where(
*DATE PARAMETER NAME*,
"<",
// ${parseInt(currentDay) + *Number of days you want in range*}
new Date(`${currentYear}-${currentMonth}-${parseInt(currentDay) + 1}`)
)
.get();

- 335
- 3
- 3