Emir Kutlugün
Emir Kutlugün

Reputation: 447

Can't convert firetstore timestamp to Flutter DateTime

I can't convert firestore timestamp to flutter date, and really tried near everything( including using Timestamp instead of DateTime in model), any idea how to fix this bug. Here's my code below

Model From Map

  factory Event.fromMap(Map<String, dynamic> map) {
    return Event(
      id: map['id'],
      organizerId: map['organizerId'],
      organizerName: map['organizerName'],
      eventTime: map['eventTime'].toDate(),
      maxApplicationCount: map['maxApplicationCount'],
      attendedUsers: List<String>.from(map['attendedUsers']),
      eventText: map['eventText'],
      location: Location.fromMap(map['location']),
    );
  }

Error

 NoSuchMethodError: Class 'int' has no instance method 'toDate'.

Using Timestamp Instead of DateTime

  factory Event.fromMap(Map<String, dynamic> map) {
    return Event(
      id: map['id'],
      organizerId: map['organizerId'],
      organizerName: map['organizerName'],
      eventTime: map['eventTime'],
      maxApplicationCount: map['maxApplicationCount'],
      attendedUsers: List<String>.from(map['attendedUsers']),
      eventText: map['eventText'],
      location: Location.fromMap(map['location']),
    );
  }

Error

flutter: type 'int' is not a subtype of type 'Timestamp'

Any idea how to convert Firestore timestamp to dateTime?

map['eventTime']

Timestamp(seconds=1620583200, nanoseconds=0)

Upvotes: 1

Views: 477

Answers (2)

KMB90
KMB90

Reputation: 63

I suggest using this package it's a real booster

package link on pub.dev : link

Usage To use the MapDescriptor package, simply import it and create a new instance of the MapDescriptor class:

import 'package:map_descriptor/map_descriptor.dart';

MapDescriptor mapDescriptor = MapDescriptor();

**Converting TimeStamp va

lues to ISO 8601 strings**

To convert TimeStamp values in a map to ISO 8601 strings, use the convertTimeStampToStr method:

Map<String, dynamic> myMap = {
  'date1': TimeStamp(2124545,6565457),
  'date2': {'date3': TimeStamp(1212154,121215545)}
};

Map<String, dynamic> result = mapDescriptor.convertTimeStampToStr(myMap);

print(result);
// output: {date1: 2023-04-24T16:47:36.975, date2: {date3: 2023-04-24T16:47:36.975}}

Converting ISO 8601 strings to TimeStamp values

To convert ISO 8601 string values in a map to TimeStamp objects, use the convertStrToTimeStamp method:

Map<String, dynamic> myMap = {
  'date1': '2023-04-24T16:47:36.975',
  'date2': {'date3': '2023-04-24T16:47:36.975'}
};

Map<String, dynamic> result = mapDescriptor.convertStrToTimeStamp(myMap);

print(result);
// output: {date1: Timestamp(seconds=1685065656, nanoseconds=975000000), date2: {date3: Timestamp(seconds=1685065656, nanoseconds=975000000)}}

Checking for TimeStamp or ISO 8601 string values

To determine if a map contains any TimeStamp or ISO 8601 string values, use the containsTimeStamp and containsISO8601Str methods, respectively:

Map<String, dynamic> myMap1 = {'date1': TimeStamp(4545412,2121454)};
Map<String, dynamic> myMap2 = {'date1': {'date3': TimeStamp(412115,121244)}, 'date2': {'date3': '2023-04-24T16:47:36.975'}};

bool containsDateTime1 = mapDescriptor.containsTimeStamp(myMap1); // true
bool containsDateTime2 = mapDescriptor.containsTimeStamp(myMap2); // false

bool containsISO8601Str1 = mapDescriptor.containsISO8601Str(myMap1); // false
bool containsISO8601Str2 = mapDescriptor.containsISO8601Str(myMap2); // true
Storing the map to the persistent storage
 Future setMap(
    String key,
    Map<String, dynamic> myMap,
  ) async {
    await initializePrefs();
    //delete the previous data to prevent error
    await prefs!.setString(key, jsonEncode({}));
    if (MapDescriptor().containsTimeStamp(myMap)) {
      myMap = MapDescriptor().convertTimeStampToStr(myMap);
    }
    //now we can use jsonEncode for myMap 
    // if we kept myMap without converting TimeStamp values
    // the code will throw an error that the method .toJson() is not allowed
    // for TimeStamp values
    return await prefs!.setString(key, jsonEncode(myMap));
  }

If the myMap parameter contains a timestamp (as determined by the containsTimeStamp method of the MapDescriptor class), the convertTimeStampToStr method of the MapDescriptor class is called to convert the timestamp to a string.

Finally, the myMap parameter is JSON-encoded and saved to the persistent storage using the setString method of the prefs instance with the specified key.

Overall, this function saves a map of key-value pairs to a persistent storage using SharedPreferences. If the map contains a timestamp, it is converted to a string before being saved. The previous data associated with the specified key is deleted before saving the new data to prevent errors.

Upvotes: 0

Mofidul Islam
Mofidul Islam

Reputation: 510

Could you just make eventTime as dynamic and try eventModel.eventTime.toDate() wherever you use it

This works for me. Set and get timestamp like this

class EventModel{
      dynamic timestamp;
      SiteModel({this.deletedTimestamp});
      EventModel.fromJson(Map<String, dynamic> json) {
        timestamp=json['timestamp'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data =<String, dynamic>{};
        data["timestamp"]=FieldValue.serverTimestamp();
        return data;
      }

Use it like this

eventModel.timestamp.toDate().toString()

Upvotes: 1

Related Questions