Reputation: 2423
I got an error when I try to get Time set data from Cloud Firestore.
I think if I set timestampsInSnapshots: true
then the issue will be fixed, but I can't set it because I use cloud_firestore: ^0.16.0
so I couldn't found how can I do this. if I use cloud_firestore: ^0.8.2+1
then I can configure the Firestore's settings. But I wanna set this configuration in version 0.16.0
About Issue:
The following _TypeError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#ec8a0):
type 'Timestamp' is not a subtype of type 'int'
The relevant error-causing widget was
StreamBuilder<QuerySnapshot>
lib/…/main/profile.dart:66
When the exception was thrown, this was the stack
#0 _ProfileState.buildExamHistoryList.<anonymous closure>.<anonymous closure>
lib/…/main/profile.dart:97
#1 MappedListIterable.elementAt (dart:_internal/iterable.dart:411:31)
#2 ListIterator.moveNext (dart:_internal/iterable.dart:340:26)
#3 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
#4 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
...
The stream where I wanna set my data from firestore:
Widget buildExamHistoryList() {
return StreamBuilder<QuerySnapshot>(
stream: usersRef.doc(widget.userID).collection('examResults').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(
child: Text("Something Went Wrong"),
);
}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Container(
padding: EdgeInsets.only(top: 100),
child: Center(
child: SpinKitFadingCircle(
color: Colors.black,
size: 50,
),
),
);
break;
default:
return Column(
children: [
ListView(
shrinkWrap: true,
children: snapshot.data.docs.map((doc) {
return Padding(
padding: const EdgeInsets.all(10),
child: ExamHistoryCard(
correctAnswersCount: doc['correctAnswersCount'],
incorrectAnswersCount: doc['incorrectAnswersCount'],
date: _examHistoryService.readTimestamp(doc['date']),
),
);
}).toList(),
),
],
);
}
},
);
}
and that is my readTimestamp
function:
String readTimestamp(int timestamp) {
var now = DateTime.now();
var format = DateFormat('HH:mm a');
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var diff = now.difference(date);
var time = '';
if (diff.inSeconds <= 0 ||
diff.inSeconds > 0 && diff.inMinutes == 0 ||
diff.inMinutes > 0 && diff.inHours == 0 ||
diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' Dünen';
} else {
time = diff.inDays.toString() + ' Gün Önce';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
} else {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
}
}
return time;
}
Upvotes: 2
Views: 1777
Reputation: 1599
Try this
String readTimestamp(Timestamp timestamp) {
var now = DateTime.now();
var format = DateFormat('HH:mm a');
var date = timestamp.toDate();
var diff = now.difference(date);
var time = '';
if (diff.inSeconds <= 0 ||
diff.inSeconds > 0 && diff.inMinutes == 0 ||
diff.inMinutes > 0 && diff.inHours == 0 ||
diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' Dünen';
} else {
time = diff.inDays.toString() + ' Gün Önce';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
} else {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
}
}
return time;
}
Upvotes: 0
Reputation: 372
The dates you get from firebase in doc['date'] is a Timestamp, not an int. You can transform it into a Date by using toDate() method or to milliseconds since epoch with toMillis() like this:
final Timestamp timestamp = doc['date'];
final DateTime date = timestamp.toDate();
final int millis = timestamp.toMillis()
Also be sure to declare the correct type you are going to be passing to your readTimestamp
function:
String readTimestamp(Timestamp timestamp) {}
or
String readTimestamp(DateTime date) {}
or
String readTimestamp(int millis) {}
Upvotes: 3
Reputation: 8383
Timestamp from Firebase will be formatted as Timestamp
or Map
.
Here DatetimeConverter
taking care of the conversion from/to json from Firebase Firestore and Cloud Functions:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
class DatetimeConverter implements JsonConverter<DateTime, dynamic> {
const DatetimeConverter();
@override
dynamic toJson(DateTime object) {
return object != null
? Timestamp.fromDate(object)
: FieldValue.serverTimestamp();
}
@override
DateTime fromJson(dynamic val) {
Timestamp timestamp;
if (val is Timestamp) {
// the firestore SDK formats the timestamp as a timestamp
timestamp = val;
} else if (val is Map) {
// cloud functions formate the timestamp as a map
timestamp = Timestamp(val['_seconds'] as int, val['_nanoseconds'] as int);
}
if (timestamp != null) {
return timestamp.toDate();
} else {
// Timestamp probably not yet written server side
return Timestamp.now().toDate();
}
}
}
Upvotes: -1