Flutter - Filter Stream based on Date picked - flutter

I have a simple flutter application where I retrieve a bunch of records from Firebase. The records contain a field called DATE, which is in DateTime format.(Date + time + TZ)
But from my application, How can I make a page where I can filter the records just for a selected DATE.
When I use .where('time', isGreaterThan : _selectedDate) , it works. But it gives all days after the selected date. I just want to filter for just ONE selected day.
Heres my Code:
Stream<QuerySnapshot> _getCurrentOders() async* {
yield* FirebaseFirestore.instance
.collection('ItemList')
.where('time', isGreaterThan: _selectedDate)
.orderBy('time', descending: false)
.snapshots();
}
I also use a DateTime picker to select a date.
DateTimeField(
initialValue: DateTime.now(),
onChanged: (val) {
setState(() {
_selectedDate = val;
});
},
format: format,
onShowPicker: (context, currentValue) {
return showDatePicker(
context: context,
firstDate: DateTime(2019),
initialDate: currentValue ?? DateTime.now(),
lastDate: DateTime(2100));
},
),
Thank you for the support!

// this gives you the first millisecond of the day
var startOfTheDay = DateTime(_selectedDate.year, _selectedDate.month, _selectedDate.day);
//and this gives you the first millisecond of the next day
var endOfTheDay = startOfTheDay.add(Duration(days: 1);
and after that you can use:
.where('time', isGreaterThan : startOfTheDay).where('time', isLessThan : endOfTheDay)

Related

How to list Firebase data filtered by date?

I want to list firebase data on page filtered by date
DatePicker to select date:
{
DateTime? pickedDate = await showDatePicker(
context: context,
locale: const Locale("tr", "TR"),
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
);
if (pickedDate != null) {
print(pickedDate);
String formattedDate = DateFormat('dd.MM.yyyy').format(pickedDate);
print(formattedDate);
setState(() {
tarihfiltre.text = formattedDate;
tarih = pickedDate;
});
}
}
Here is the code I wrote for these other filters:
FirestoreListView<Map<String, dynamic>>(
shrinkWrap: true,
query: FirebaseFirestore.instance.collection('odemeler'),
itemBuilder: (context, snapshot) {
Map<String, dynamic> odeme = snapshot.data();
if (searchString == '' ||
odeme['firma'].toString().toLowerCase().contains(searchString.toLowerCase()) ||
odeme['alici'].toString().toLowerCase().contains(searchString.toLowerCase()) ||
odeme['odeme'].toString().toLowerCase().contains(searchString.toLowerCase()) ||
odeme['bitis'] == tarih) {
return Column(children: [
const SizedBox(height: 10),
// Expanded(
// child: FutureBuilder(
// // Our existing list code
// ),
// ),
SizedBox(...
...)
odeme['bitis'] == tarih)
The above line is the code I tried for filtering by date, but it doesn't work.
How can I specify and list the data that is on the same date as the date I selected from the calendar?
You can use orderBy or Where clause to filter your data from firestore.
According to this link you should use the where method. Combine that with firebase flutter docs (relevant example here), you should be able to accomplish this using something like:
FirebaseFirestore.instance
.collection('odemeler')
.where('bitis', isEqualTo: 'tarih')
.where(...) //another where condition

schedule conflict flutter firebase in adding a date that has already been taken

I am trying to achieve schedule conflict in my uni app, itenerary, where a user wouldnt be allowed to add a trip that has a date that is already taken.
I am struggling to get the right query but this is what i have tried
List dateinput= [];
DateTime? pickeddate = await showDatePicker(context: context,
initialDate:DateTime.now(),
firstDate: DateTime.now().subtract(Duration(days: 0)),
lastDate: DateTime(2025));
setState(() {
date.text= DateFormat('yyyy-MM-dd').format(pickeddate!);
});
//my query
final collection = FirebaseFirestore.instance.collection('UserTrip')
.orderBy('tripDate')
.get()
.then((value) =>
value.docs.forEach((element) {
List data1 = element.data() as List;
dateinput.add(data1);
print(dateinput);
}));
//and I'm trying to implement that return error on pressed on the add trip button
if (dateinput.contains(date.text)) {
//return error
} else {
uploadFile();}

I wants to show selected date in date picker when I tap again on date picker using flutter

Currently initialDate is set to DateTime.now() initially today's date must shown but when I select any date and again opens the Date Picker initial date should be the one which I have selected previously.
How to do this:
child: TextField(
onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(
1991), //DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2025),
// onConfirm:widget.onChanged,
).then((pickedDate) {
if (pickedDate != null) {
// print(
// pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('yyyy-MM-dd').format(pickedDate);
print(formattedDate);
setState(() {
startDtcontroller.text = formattedDate;
//set output date to TextField value.
});
//print(startDtcontroller.text);
//formatted date output using intl package => 2021-03-16
//you can implement different kind of Date Format here according to your requirement
// DateFormat df = new DateFormat("yyyy-MM-dd");
// String stDate = df.format(pickedDate);
// print(stDate);
widget.onChanged(formattedDate);
} else {
print("Date is not selected");
}
});
You need to save that value somewhere...
DateTime? selectedDateTime;
...
child: TextField( onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: selectedDateTime ?? DateTime.now(),
...).then(pickedDate) { setState(() => selectedDateTime = pickedDate);}

Flutter: showDatePicker firstdate and lastdate from same week

I am trying to give user an option to select date between 7 days.
Like today is 2nd March then user can select any date before 10th March.
My current code is showing first date as 01/01/03 i am not sure why it is giving me this date.
Here is the code.
_pickedDate() async {
rescheduleddate = await showDatePicker(
context: context,
firstDate: DateTime(DateTime.now().day + 1),
lastDate: DateTime(DateTime.now().day + 7),
initialDate: DateTime(DateTime.now().day + 1),
);
if (rescheduleddate != null) {
setState(() {
pickeddate = rescheduleddate;
});
}
}
I am not sure what am i doing wrong because if i add year instead of day then it is working fine.
I managed to solve this one.
_pickedDate() async {
rescheduleddate = await showDatePicker(
context: context,
firstDate: DateTime.now().add(new Duration(days: 1)),
lastDate: DateTime.now().add(new Duration(days: 7)),
initialDate: DateTime.now().add(new Duration(days: 1)),
);
if (rescheduleddate != null) {
setState(() {
pickeddate = rescheduleddate;
});
}
}
I think the issue might be that you aren't properly adding a duration to the current DateTime object. By calling .day you are just getting the number of the day as an integer, which you're then trying to plug back into a new DatePicker as an argument. For example, if today is March 2nd, DateTime.now().day would return 2, so your firstDate value is currently trying to evaluate what DateTime(3) is (if you inspect the DateTime function, the first argument is the year as an integer, so it's setting the date to 01/01/03). Try doing this:
rescheduleddate = await showDatePicker(
context: context,
firstDate: DateTime.now().add(Duration(days: 1)),
lastDate: DateTime.now().add(Duration(days: 7)),
initialDate: DateTime.now().add(Duration(days: 1)),
);

how to compare showdatepicker + showtimepicker results with current date (datetime.now())

I can get the date time values with date and time picker. I want to combine the date and time values ​​I have obtained and compare them with the current date (DateTime.now() format).
How can I do it?
Future _selectDayAndTime(BuildContext context) async {
DateTime _selectedDay = await showDatePicker(
context: context,
initialDate: _date ?? DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2100),
builder: (BuildContext context, Widget child) => child
);
TimeOfDay _selectedTime = await showTimePicker(
context: context,
initialTime: _time ?? TimeOfDay.now(),
);
if(_selectedDay != null && _selectedTime != null) {
setState(() {
_date = _selectedDay;
_time = _selectedTime;
});
debugPrint("Day result : $_date");
debugPrint("Time result : $_time");
}
}
Result
I/flutter ( 9596): Day result : 2020-01-16 00:00:00.000
I/flutter ( 9596): Time result : TimeOfDay(18:30)
TimeOfDay holds only hour and minutes. showDatePicker() returns a DateTime object, although it contains only year, month and day which are meaningful. You may update this DateTime object's hour and minutes with that of TimeofDay.
A vague code would as shown below.
var _date = _selectedDay;
var _time = _selectedTime;
var updatedDateTime = new DateTime(_date.year, _date.month, _date.day, _time.hour, _time.minute, _date.second);
And now, you can use standart DateTime class methods, to compare this updatedDateTime with DateTime.now().
This might help you :
var date = DateTime.now();
var time = TimeOfDay(hour: 12, minute: 00);
// Combined DateTime and TimeOfDay
var pickedTime = DateTime(date.year, date.month, date.day, time.hour, time.minute);
// returns -1 if pickedTime is before, 1 if after, 0 if equal.
var comparison = pickedTime.compareTo(date);
// time between now and the time of day.
var duration = Duration(milliseconds: date.millisecondsSinceEpoch - pickedTime.millisecondsSinceEpoch);