Im reading some data(messages) from Cloud Firestore and in a document i have a timestamp field for time.
I have a Stream:
Stream<QuerySnapshot> get chats {
return chatCollection.document(roomid).collection("messages").snapshots();
}
for getting the messages if a an update occurs in my database (ex New message).
So when i start the app it reads all the data(messages) from the DB and i print them in my app. Here is what my console printing the messages every time i get a new snapshot:
D/ViewRootImpl@a0e5145[MainActivity]( 3045): MSG_RESIZED: frame=Rect(0, 0 - 1440, 2560) ci=Rect(0, 96 - 0, 1164) vi=Rect(0, 96 - 0, 1164) or=1
D/ViewRootImpl@a0e5145[MainActivity]( 3045): Relayout returned: old=[0,0][1440,2560] new=[0,0][1440,2560] result=0x1 surface={valid=true 492514541568} changed=false
I/flutter ( 3045): DEBUG: TEST-MESSAGE what??? 2020-10-09 22:30:12.249
I/flutter ( 3045): DEBUG: TEST-MESSAGE λολ 2020-10-09 21:59:58.212
I/flutter ( 3045): DEBUG: TEST-MESSAGE gamieste 2020-10-09 22:33:10.902
I/flutter ( 3045): DEBUG: TEST-MESSAGE holly 2020-10-09 22:26:39.672
I/flutter ( 3045): DEBUG: TEST-MESSAGE γφ 2020-10-09 22:08:47.617
I/flutter ( 3045): DEBUG: TEST-MESSAGE ελα 2020-10-09 22:13:38.167
I/flutter ( 3045): DEBUG: TEST-MESSAGE see re 2020-10-09 22:29:14.277
I/flutter ( 3045): DEBUG: TEST-MESSAGE ιξι 2020-10-09 22:10:07.442
I/flutter ( 3045): DEBUG: TEST-MESSAGE ολα καλα ρε 2020-10-09 22:05:00.703
I/flutter ( 3045): DEBUG: TEST-MESSAGE what??? 2020-10-09 22:30:12.249
I/flutter ( 3045): DEBUG: TEST-MESSAGE λολ 2020-10-09 21:59:58.212
I/flutter ( 3045): DEBUG: TEST-MESSAGE gamieste 2020-10-09 22:33:10.902
I/flutter ( 3045): DEBUG: TEST-MESSAGE holly fuck 2020-10-09 22:26:39.672
I/flutter ( 3045): DEBUG: TEST-MESSAGE γφ 2020-10-09 22:08:47.617
I/flutter ( 3045): DEBUG: TEST-MESSAGE ελα μου 2020-10-09 22:13:38.167
So no problem on that. The problem occurs when i add a new document(message) in my DB from my code, then immediately it gets the update from the DB and i have the new snapshot with the new list of messages. But for about 0.5 sec i get an error on the screen oh my android and then it gets normal and has loaded all messages correctly. The error is a null pointer for a specific field of the document. TIME. Time is timestamp field in my Cloud Firestore DB.
So here is the error:
The following NoSuchMethodError was thrown building:
The method 'toDate' was called on null.
Receiver: null
Tried calling: toDate()
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _ChatScreenState._buildMessage (package:flutter_firebase_chat_app/screens/chat/chat_screen.dart:48:43)
#2 _ChatScreenState.build.<anonymous closure>.<anonymous closure> (package:flutter_firebase_chat_app/screens/chat/chat_screen.dart:226:40)
#3 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:448:22)
#4 SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1136:67)
#5 _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:140:29)
#6 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1136:26)
#7 SliverMultiBoxAdaptorElement.performRebuild.processElement (package:flutter/src/widgets/sliver.dart:1082:66)
You will see that its just a null exception. The thing is why im getting a null for a Time field only when i upload a message. And the thing is that after that the message comes again from another snapshot with no-null value!! If you look on the error code segment i have printed the whole object and in the top right corner you will see that time field has null value. I made an if statement to print the whole object whenever time field is null.
So at last the thing i think is causing this is that time field is a timestamp and when i upload the data i give it a value of ServerTimestamp().
Code here:
Future sendMessage(Message message) async {
if (message.senderId != AuthService.myUid) return null;
return await chatCollection.document(roomid).collection("messages").add({
"message": message.text,
"sender": message.senderId,
"receiver": message.receiverId,
"time": FieldValue.serverTimestamp(),
"isLiked": message.isLiked,
"unread": message.unread,
});
}
As you can see the Time field is the only one that takes that FieldValue.serverTimestamp() , so i think that somehow i get snapshot of the document before the Timestamp value to field time has been assigned. And after i get it all (with the Time field being no-Null)
Any ideas?