gpt4 book ai didi

firebase - 云 Firestore 中的时间字段 serverTimestamp() 在第一个快照上返回 null

转载 作者:行者123 更新时间:2023-12-03 19:02:46 27 4
gpt4 key购买 nike

我正在从 Cloud Firestore 读取一些数据(消息),并且在文档中我有一个 timestamp时间字段。
我有一个流:

Stream<QuerySnapshot> get chats {
return chatCollection.document(roomid).collection("messages").snapshots();
}
用于在我的数据库中发生更新时获取消息(例如新消息)。
因此,当我启动应用程序时,它会从数据库中读取所有数据(消息)并将它们打印在我的应用程序中。
这是我每次获得新快照时控制台打印消息的内容:
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
所以没问题。当我从我的代码在我的数据库中添加一个新文档(消息)时,会出现问题,然后它立即从数据库获取更新,并且我拥有带有新消息列表的新快照。但是在大约 0.5 秒内,我在屏幕上出现错误,哦,我的 android,然后它恢复正常并正确加载了所有消息。错误是文档特定字段的空指针。 时间 .时间是我的 Cloud Firestore 数据库中的时间戳字段。
所以这里是错误:
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)
你会看到它只是一个空异常。这就是为什么我只有在上传消息时才为时间字段获取空值。问题是,在那之后消息再次来自另一个快照 非空值 !!如果您查看错误代码段,我已经打印了整个对象,并且在右上角您会看到 时间字段有空值 .每当时间字段为空时,我都做了一个 if 语句来打印整个对象。
所以最后我认为导致这个的事情是时间字段是一个时间戳,当我上传数据时,我给它一个值 ServerTimestamp() .
代码在这里:
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,
});
}
如您所见,时间字段是唯一一个接受 FieldValue.serverTimestamp() 的字段。 ,所以我认为我以某种方式在将时间戳值分配给字段时间之前获得了文档的快照。在我得到这一切之后(时间字段不为空)
有任何想法吗?

最佳答案

我也遇到了同样的问题。经过广泛搜索,我找到了这个 article很有用。
它有助于了解问题和流程导致问题。
使用 DateTime.now()不是解决方案,因为使用 FieldValue.serverTimestamp() 的主要目的是
是同步不同设备之间的时间,即DateTime.now()不解决。
现在,关于 FieldValue 的 NULL 问题:
我也用过 sortTime.toDate().toString()按照建议 Here ,但在时间戳上获得 NULL,因为:

  • 发送消息时,会向服务器发送写请求,但数据尚不可用。
  • builder 正在尝试提取数据并获取空值。
  • 数据可用,NULL 替换为真实数据。
    为了解决那几毫秒的故障,我尝试了多种解决方案,但发现这是最简单的:
    放置一个空字符串直到该数据可用,UI 将是空的大约 0.5 秒,但根据我的经验,它仍然看起来不错。

  • 电话:DR
    final sortTime = snapshot.data.documents[index].data()["sortTime"];
    String serverTime = sortTime == null ? "" : sortTime.toDate().toString();
    考虑这个 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);
    }

    获取消息
    getConversationMessages(String chatRoomId) async {
    return await chatsCollection
    .doc(chatRoomId)
    .collection("chats")
    .orderBy("sortTime", descending: true)
    .snapshots();
    }
    Stream chatMessagesStream;
    void initState(){
    getConversationMessages(widget.chatRoomId)
    .then((value){
    setState(() {
    chatMessagesStream = value;
    });
    });
    super.initState();
    }
    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);
    }
    );
    }
    },
    );
    }

    关于firebase - 云 Firestore 中的时间字段 serverTimestamp() 在第一个快照上返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64287252/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com