Pan*_*iss 8 timestamp firebase flutter google-cloud-firestore
我从 Cloud Firestore 读取一些数据(消息),在文档中我有一个timestamp时间字段。\n我有一个流:
Stream<QuerySnapshot> get chats {\n return chatCollection.document(roomid).collection("messages").snapshots();\n }\nRun Code Online (Sandbox Code Playgroud)\n用于在我的数据库中发生更新(例如新消息)时获取消息。
\n因此,当我启动应用程序时,它会从数据库读取所有数据(消息)并打印出来。\n这是每次获取新快照时我的控制台和消息的样子:
\nD/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\nD/ViewRootImpl@a0e5145[MainActivity]( 3045): Relayout returned: old=[0,0][1440,2560] new=[0,0][1440,2560] result=0x1 surface={valid=true 492514541568} changed=false\nI/flutter ( 3045): DEBUG: TEST-MESSAGE what??? 2020-10-09 22:30:12.249\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xbb\xce\xbf\xce\xbb 2020-10-09 21:59:58.212\nI/flutter ( 3045): DEBUG: TEST-MESSAGE gamieste 2020-10-09 22:33:10.902\nI/flutter ( 3045): DEBUG: TEST-MESSAGE holly 2020-10-09 22:26:39.672\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xb3\xcf\x86 2020-10-09 22:08:47.617\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xb5\xce\xbb\xce\xb1 2020-10-09 22:13:38.167\nI/flutter ( 3045): DEBUG: TEST-MESSAGE see re 2020-10-09 22:29:14.277\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xb9\xce\xbe\xce\xb9 2020-10-09 22:10:07.442\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xbf\xce\xbb\xce\xb1 \xce\xba\xce\xb1\xce\xbb\xce\xb1 \xcf\x81\xce\xb5 2020-10-09 22:05:00.703\nI/flutter ( 3045): DEBUG: TEST-MESSAGE what??? 2020-10-09 22:30:12.249\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xbb\xce\xbf\xce\xbb 2020-10-09 21:59:58.212\nI/flutter ( 3045): DEBUG: TEST-MESSAGE gamieste 2020-10-09 22:33:10.902\nI/flutter ( 3045): DEBUG: TEST-MESSAGE holly fuck 2020-10-09 22:26:39.672\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xb3\xcf\x86 2020-10-09 22:08:47.617\nI/flutter ( 3045): DEBUG: TEST-MESSAGE \xce\xb5\xce\xbb\xce\xb1 \xce\xbc\xce\xbf\xcf\x85 2020-10-09 22:13:38.167\nRun Code Online (Sandbox Code Playgroud)\n所以这没有问题。当我从代码中在数据库中添加新文档(消息),然后立即从数据库获取更新并且我拥有包含新消息列表的新快照时,就会出现问题。但大约 0.5 秒后,我的 Android 屏幕上出现错误,然后它变得正常并正确加载了所有消息。该错误是文档特定字段的空指针。时间。时间是我的 Cloud Firestore DB 中的时间戳字段。
\n所以这是错误:
\nThe following NoSuchMethodError was thrown building:\nThe method 'toDate' was called on null.\nReceiver: null\nTried calling: toDate()\n\nWhen the exception was thrown, this was the stack:\n#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)\n#1 _ChatScreenState._buildMessage (package:flutter_firebase_chat_app/screens/chat/chat_screen.dart:48:43)\n#2 _ChatScreenState.build.<anonymous closure>.<anonymous closure> (package:flutter_firebase_chat_app/screens/chat/chat_screen.dart:226:40)\n#3 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:448:22)\n#4 SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1136:67)\n#5 _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:140:29)\n#6 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1136:26)\n#7 SliverMultiBoxAdaptorElement.performRebuild.processElement (package:flutter/src/widgets/sliver.dart:1082:66) \nRun Code Online (Sandbox Code Playgroud)\n您将看到它只是一个空异常。问题是为什么只有当我上传消息时,时间字段才会为空。问题是,此后消息再次来自另一个具有非空值的快照!如果您查看错误代码段,我已经打印了整个对象,并且在右上角您将看到时间字段具有空值。我做了一个 if 语句,每当时间字段为空时就打印整个对象。
\n所以最后我认为导致这个问题的是时间字段是一个时间戳,当我上传数据时我给它一个值ServerTimestamp()。\n这里的代码:
Future sendMessage(Message message) async {\n if (message.senderId != AuthService.myUid) return null;\n return await chatCollection.document(roomid).collection("messages").add({\n "message": message.text,\n "sender": message.senderId,\n "receiver": message.receiverId,\n "time": FieldValue.serverTimestamp(),\n "isLiked": message.isLiked,\n "unread": message.unread,\n });\n }\nRun Code Online (Sandbox Code Playgroud)\n正如您所看到的,“时间”字段是唯一采用该字段的字段FieldValue.serverTimestamp(),因此我认为在将时间戳值分配给字段时间之前,我会以某种方式获取文档的快照。当我得到这一切之后(时间字段不为空)
有任何想法吗?
\n我也遇到了同样的问题。经过广泛的搜索,我发现这篇文章非常有用。它有助于理解问题以及流程导致问题的原因。
使用DateTime.now()
不是解决方案,因为使用的主要目的FieldValue.serverTimestamp()
是在不同设备之间同步时间,但这并DateTime.now()不能解决问题。
现在,关于 FieldValue 的 NULL 问题:我也sortTime.toDate().toString()按照建议使用了Here,但在时间戳上得到 NULL,因为:
翻译:博士
final sortTime = snapshot.data.documents[index].data()["sortTime"];
String serverTime = sortTime == null ? "" : sortTime.toDate().toString();
Run Code Online (Sandbox Code Playgroud)
将此 Dart 代码视为一个简短的示例来解释:
发送消息功能:
/// on pressed action (send to firebase, and show message)
/// consider the messageController gets the input from the user
sendMessage(MyUser myUser) async {
if (messageController.text.isNotEmpty){
Map<String, dynamic> chatMessage = {
"senderUid" : myUser.userId,
"text" : messageController.text,
"sortTime" : FieldValue.serverTimestamp(),
};
messageController.text = "";
await addConversationMessages(widget.chatRoomId, chatMessage);
}
}
Future addConversationMessages(String chatRoomId, chatMessage) async {
await chatsCollection
.doc(chatRoomId)
.collection("chats")
.add(chatMessage);
}
Run Code Online (Sandbox Code Playgroud)
获取消息
getConversationMessages(String chatRoomId) async {
return await chatsCollection
.doc(chatRoomId)
.collection("chats")
.orderBy("sortTime", descending: true)
.snapshots();
}
Run Code Online (Sandbox Code Playgroud)
Stream chatMessagesStream;
void initState(){
getConversationMessages(widget.chatRoomId)
.then((value){
setState(() {
chatMessagesStream = value;
});
});
super.initState();
}
Run Code Online (Sandbox Code Playgroud)
Widget ListViewMessages(MyUser myUser){
return StreamBuilder(
stream: chatMessagesStream,
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFF087E8B)),
)
);
} else {
return ListView.builder(
reverse: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
final msgText = snapshot.data.documents[index].data()["text"];
final msgUid = snapshot.data.documents[index]
.data()["senderUid"];
final sortTime = snapshot.data.documents[index].data()["sortTime"];
String serverTime = sortTime == null ? "" : sortTime.toDate().toString();
return _buildMessage(
msgText, serverTime, msgUid);
}
);
}
},
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3200 次 |
| 最近记录: |