I couldn't insert data to firestore on flutter - flutter

I couldn't insert the duration in firestore on flutter. In 'field6'. type of data from firestore should match with field6 .How to do that?
'field5' inserting correctly
enter image description here
CODE
duration calculating method
DateDuration? duration;
void calAge() {
DateTime? birthday = selectedDate;
duration = AgeCalculator.age(birthday!);
print('Your age is $duration');
}
inset firestore
void send() {
FirebaseFirestore.instance.collection("data").doc().set({
"field5": selectedDate,
"field6": Duration(duration).toString(),
});
}
enter image description here

Saving dates in firestore can be tricky if you need to save the current datetime you need to use FieldValue.serverTimestamp() provided by firebase but if you need to be more dynamic, you can save it as a string then when getting it back from firestore you will use DateTime.parse(your string date) also you can save it as an int and when getting it you use DateTime.fromMicrosecondsSinceEpoch(your int date) if your time stamp is in micro seconds but use this if its in seconds DateTime.fromMillisecondsSinceEpoch(your int date)

Related

How can I send and receive two types of data from one single field in firestore for flutter?

I have two textfields in my flutter app. I used showDatePicker on the first one when tapped and showTimePicker on the second one when tapped (to let a user choose a certain date and time).
I am using a class model to send and receive date and time both from one variable:
DateTime? taskDate; // Time as well
I thought about sending them separately but look what happens in firebase when I send them both together :
One timestamp field that has date and time seperated ( like a map).
My question is how can I point to one of them ( date or time) in Firestore so I can do some actions on them?
For example I want to add a task in 13 January 20203 and I want this to be saved in date field and the time to be saved in time field. What you see in the picture isn't picked date and time.
This is the code of sending data using a model and bloc state managment :
TaskModel? taskModel;
void addTask({
required String title,
required DateTime date,
}) {
emit(AddPostLoadingState());
taskModel = TaskModel(
taskTitle: title,
taskDate: date,
name: userModel!.name,
uid: userModel!.uId);
FirebaseFirestore.instance
.collection('tasks')
.add(taskModel!.toJson())
.then((value) {
getTask();
}).catchError((error) {
print(error);
emit(AddPostErrorState(error));
});
}
And since I know that datetime recieved as timestamp in firestore .. I changed it in the type when I get data :
void getTask() {
emit(GetTaskLoadingState());
FirebaseFirestore.instance
.collection('tasks')
.where('uid', isEqualTo: uId)
.orderBy('taskDate')
.get()
.then((value) {
tasks = []; // Global List<TaskModel>
for (var element in value.docs) {
data['taskDate'] = DateTime.fromMillisecondsSinceEpoch(
data['taskDate'].seconds * 1000);
tasks.add(TaskModel.fromJson(data));
}
emit(GetTaskSuccessState());
}).catchError((error) {
print(error.toString());
emit(GetTaskErrorState(error: error));
});
}
The Firestore Timestamp field is an atomic value that contains both date and time. There is no way to set the date and time of the field separately, as it's stored as a single value in the database.
If you want to manipulate the date and time separate in the database, consider storing them as separate fields (e.g. in a map as you already describe) yourself. Then you'll need to convert to/from a DateTime in your code when reading from/writing to the database.

Convert milliseconds to Firestore date

In Flutter I convert dates to milliseconds like this:
static DateTime createDateTimeNow() {
return DateTime(DateTime.now().year, DateTime.now().month,
DateTime.now().day, 0, 0, 0, 0, 0);
}
// This create a number value like 1660341600000
final Number millisecondsNow = Helpers.createDateTimeNow().toUtc().millisecondsSinceEpoch;
// I can also format is as String to be presented based on the language
final String dateNow = DateFormat.yMMMMd(language).format(millisecondsNow);
Now I have Firebase Cloud Functions that should read these dates and send notification when they expire, but could I convert this number to a normal date in Firestore?
From Flutter I do something like this:
final DateTime dateNow = DateTime.fromMillisecondsSinceEpoch(1660341600000);
You can use fromMillis( ) method from firestore.timestamp which can create new timestamp from the given number of milliseconds.
firestore.Timestamp.fromMillis(milliseconds)
You can refer these documents for more details firestore timestamp from milliseconds and Firestore Timestamp
You're working too hard. Firestore Timestamp to Dart DateTime:
final dt = aTimestamp.toDate();
and from DateTime to Timestamp:
final ts = Timestamp.fromDate(aDt);
as described in https://pub.dev/documentation/cloud_firestore_platform_interface/latest/cloud_firestore_platform_interface/Timestamp-class.html
and there's no need to think about "milliseconds".

Formatting Timestamp from Cloud Firestore to Date in Flutter

I have 2 fields: created_at and updated_at field in my DB on Cloud Firestore. They are of type Timestamp.
In my Model, I have also created the respective fields like so
class User {
String id;
String firstName;
String lastName;
Timestamp created_at;
Timestamp updated_at;
}
I have the respective fromMap and toMap functions in my models. In my view user screen, how do I format my created_at and updated_at fields and display them in Text widgets as 8 May, 2020?
Thanks.
You can convert a Timestamp to a Date like so:
DateTime date = created_at.toDate();
And if you want to display it as a text you can convert your date like this:
String dateString = DateFormat('dd MMM, yyyy').foramt(date);
Therefore you need the intl Package: https://pub.dev/packages/intl

Timestamp to LocalDateTime conversion

I am reading a date from Firestore which is of type Timestamp and I want it converted as a LocalDateTime type.
To do so, I used the following procedure:
Convert the Timestamp to a DateTime
Use the .dateTime method of LocalDateTime to convert it to a LocalDateTime
Manually adjust it to my local time
LocalDateTime.dateTime(entity.start.toDate()).addHours(2),
Although entity.start.toDate() has my local time the .dateTime does some adjustments and I get some other time.
Also, this method is prone to errors sinve I am adjusting something manually.
Another way to do so would be the following but I find it too long:
DateTime hStartDate = entity.start.toDate();
LocalDateTime(hStartDate.year,hStartDate.month,hStartDate.day,hStartDate.hour,hStartDate.minute,0)
Any suggestions?
I had a similar issues I wasnt able to find a way to convert Timestamp String to Timestamp object again.
So i used this way out.
When you save data to firestore:
Use -
DateTime.now().toString()
Example :
await Firestore.instance
.collection("users/$docId/tokens")
.document(fcm.deviceToken)
.setData({
"token": fcm.deviceToken,
"timestamp": DateTime.now().toString()
});
When u get data from firestore and get the timestamp string:
Use this to get DateTime object -
DateTime dateTime = DateTime.parse(timestamp)
Use this to get TimeOfDay object -
TimeOfDay timeOfDay = TimeOfDay.fromDateTime(dateTime);
timeOfDay.format(context);
You can achieve this by using toLocal ( ) method.
something like this.
_getDate(//timestamp, "yyyy.dd.MM, HH:mm");
String _getDate(int timestamp, String dateFormat) {
DateTime date = DateTime.fromMillisecondsSinceEpoch(
timestamp * 1000,
).toLocal();
String formattedDateTime = DateFormat(dateFormat).format(date);
return formattedDateTime;
}

Flutter - TimeOfDay to Firestore timestamp then into DateTime?

I have two fields of type TimeOfDay in a model class, which is called startTime and endTime, how do i store this type into a firestore field, as a Timestamp somehow? What i want to achieve is to pick a time like start: 12:00 , end: 13:00 from a timepicker then store it to firestore, and then when reading from firestore i need the time to be of type DateTime, in the format of "12:00" in order to work with this in the weekday calendar widget where the start and end time properties is of type DateTime. Is this possible?