Firebase 颤振未读消息标记断言失败:布尔表达式不能为null

Firebase 颤振未读消息标记断言失败:布尔表达式不能为null,firebase,flutter,Firebase,Flutter,我是一个新手,我试图展示我的用法,它们有一个未读的消息,我读了一篇文章,展示了如何做到这一点,但我得到了这个错误失败的断言:布尔表达式不能为null 当我将布尔值isread设置为true时,它不会显示我的徽章;当我将其设置为false时,它会显示发送方和接收方的徽章,并且不会消失 class ViewLayout extends StatelessWidget { final User contact; final ChatMethods _chatMethods = ChatMet

我是一个新手,我试图展示我的用法,它们有一个未读的消息,我读了一篇文章,展示了如何做到这一点,但我得到了这个错误
失败的断言:布尔表达式不能为null
当我将布尔值isread设置为true时,它不会显示我的徽章;当我将其设置为false时,它会显示发送方和接收方的徽章,并且不会消失

 class ViewLayout extends StatelessWidget {
  final User contact;
  final ChatMethods _chatMethods = ChatMethods();

  ViewLayout({
    @required this.contact,
  });

  bool isread;
  Map<dynamic, dynamic> chatlist;
  @override
  Widget build(BuildContext context) {
    final UserProvider userProvider = Provider.of<UserProvider>(context);
    FirebaseUser user;
    if (chatlist != null) {
      if (chatlist['senderId'] == user.uid) {
        isread = true;
      } else {
        isread = chatlist['isread'] == null ? true : chatlist['isread'];
      }
    }
    return StreamBuilder(
      builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasData) {
          var docList = snapshot.data.documents;

          if (docList.isNotEmpty) {
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        }

        return CustomTile(
            mini: false,
            onTap: () => Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => ChatScreen(
                    receiver: contact,
                  ),
                )),
            title: Text(
              (contact != null ? contact.name : null) != null
                  ? contact.name
                  : "..",
              style: TextStyle(
                  color: Colors.white, fontFamily: "Arial", fontSize: 19),
            ),
            subtitle: LastMessageContainer(
              stream: _chatMethods.fetchLastMessageBetween(
                senderId: userProvider.getUser.uid,
                receiverId: contact.uid,
              ),
            ),
            leading: Container(
              constraints: BoxConstraints(maxHeight: 60, maxWidth: 60),
              child: Stack(
                children: <Widget>[
                  CachedImage(
                    contact.profilePhoto,
                    radius: 80,
                    isRound: true,
                  ),
                  OnlineDotIndicator(
                    uid: contact.uid,
                  ),
                ],
              ),
            ),
            trailing: Column(children: <Widget>[
              Row(children: <Widget>[
                isread
                    ? Container()
                    : Icon(Icons.brightness_1, color: Colors.red[400], size: 15)
              ]),
            ]));
      },
    );
  }
}
class ViewLayout扩展了无状态小部件{
最终用户联系;
final ChatMethods_ChatMethods=ChatMethods();
视图布局({
@需要这个。联系,
});
布尔伊斯雷德;
地图聊天列表;
@凌驾
小部件构建(构建上下文){
最终用户提供者UserProvider=Provider.of(上下文);
FirebaseUser用户;
if(聊天列表!=null){
if(chatlist['senderId']==user.uid){
isread=true;
}否则{
isread=chatlist['isread']==null?true:chatlist['isread'];
}
}
返回流生成器(
生成器:(上下文,异步快照){
if(snapshot.hasData){
var docList=snapshot.data.documents;
if(docList.isNotEmpty){
}否则{
返回中心(
子对象:CircularProgressIndicator(),
);
}
}
返回自定义磁砖(
米尼:错,
onTap:()=>Navigator.push(
上下文
材料路线(
生成器:(上下文)=>ChatScreen(
接收人:联系人:,
),
)),
标题:正文(
(contact!=null?contact.name:null)!=null
?联系人姓名
: "..",
样式:TextStyle(
颜色:Colors.white,字体系列:“Arial”,字体大小:19),
),
字幕:LastMessageContainer(
流:_chatMethods.fetchLastMessageBetween(
senderId:userProvider.getUser.uid,
收款人:contact.uid,
),
),
领先:集装箱(
约束:框约束(最大高度:60,最大宽度:60),
子:堆栈(
儿童:[
恶病质图像(
联系人:profilePhoto,
半径:80,
是的,
),
在线指示器(
uid:contact.uid,
),
],
),
),
尾随:列(子项:[
世界其他地区(儿童:[
伊斯雷德
?容器()
:Icon(Icons.brightness_1,颜色:Colors.red[400],大小:15)
]),
]));
},
);
}
}
这是我的子收藏

    Future updateChatRequestField(
    String documentID, String lastMessage, chatID, _currentUserId) async {
  final DocumentReference convoDoc =
      Firestore.instance.collection('messages').document(chatID);

  convoDoc.setData(<String, dynamic>{
    'chatlist': <String, dynamic>{
      'senderId': sender.uid,
      'receiverId': widget.receiver.uid,
      'message': lastMessage,
      'timestamp': DateTime.now().millisecondsSinceEpoch,
      'isread': false,
    },
    'users': <String>[sender.uid, widget.receiver.uid]
  });
}
Future updateCatRequestField(
字符串documentID、字符串lastMessage、chatID、_currentUserId)异步{
最终文件参考文件=
Firestore.instance.collection('messages').document(chatID);
convoDoc.setData({
“聊天列表”:{
“senderId”:sender.uid,
“receiverId”:widget.receiver.uid,
“消息”:最后一条消息,
“时间戳”:DateTime.now().millissecondssinceepoch,
“isread”:错误,
},
“用户”:[sender.uid,widget.receiver.uid]
});
}
更新isread方法

     Widget chatMessageItem(DocumentSnapshot snapshot) {
    if (!snapshot['isread'] && snapshot['receiverId'] == _currentUserId) {
      updateMessageRead(snapshot, chatID);
    }
    et.Message _message = et.Message.fromMap(snapshot.data);
    return Container(
      margin: EdgeInsets.symmetric(vertical: 15),
      child: Container(
        alignment: _message.senderId == _currentUserId
            ? Alignment.centerRight
            : Alignment.centerLeft,
        child: _message.senderId == _currentUserId
            ? senderLayout(_message)
            : receiverLayout(_message),
      ),
    );
  }

  updateMessageRead(DocumentSnapshot doc, String chatID) {
    final DocumentReference documentReference = Firestore.instance
        .collection('messages')
        .document(sender.uid)
        .collection(widget.receiver.uid)
        .document(doc.documentID);

    documentReference.setData(<String, dynamic>{'isread': true}, merge: true);
  }
Widget chatMessageItem(文档快照快照){
如果(!snapshot['isread']&&snapshot['receiverId']==\u currentUserId){
updateMessageRead(快照、聊天ID);
}
et.Message _Message=et.Message.fromMap(snapshot.data);
返回容器(
边缘:边缘组。对称(垂直:15),
子:容器(
对齐方式:_message.senderId==\u currentUserId
?对准中心右侧
:Alignment.centerLeft,
子项:_message.senderId==\u currentUserId
?发送者布局(_消息)
:接收方布局(_消息),
),
);
}
updateMessageRead(文档快照文档,字符串chatID){
final DocumentReference=Firestore.instance
.collection('消息')
.document(sender.uid)
.collection(widget.receiver.uid)
.document(doc.documentID);
setData({'isread':true},merge:true);
}

您使用的是无状态小部件,因此isread的值永远不会更新。您应该扩展StatefulWidget而不是无状态Widget,将isread置于状态并使用setState()更新其值

我没有试过,但类似的方法可能会奏效:

/// This is your widget with its constructor
class ViewLayout extends StatefulWidget {
  final User contact;

  ViewLayout({
    @required this.contact,
  });

  @override
  State<StatefulWidget> createState() => _ViewLayoutState();
}

// This is the state of your widget
class _ViewLayoutState extends State<ViewLayout> {
  final ChatMethods _chatMethods = ChatMethods();

  bool isread;
  Map<dynamic, dynamic> chatlist;
  
  @override
  Widget build(BuildContext context) {
    final UserProvider userProvider = Provider.of<UserProvider>(context);
    FirebaseUser user;
    if (chatlist != null) {
      if (chatlist['senderId'] == user.uid) {
        // setState notifies you widget that its state changed. On these notifications, the widget will rebuild itself
        setState(() {
          isread = true;
        });
      } else {
        setState(() {
          // A quickest way to say 'chatlist['isread'] == null ? true : chatlist['isread']'
          isread = chatlist['isread'] ?? true;
        });
      }
    }
    return StreamBuilder(
      builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasData) {
          var docList = snapshot.data.documents;

          if (docList.isNotEmpty) {
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        }

        return CustomTile(
            mini: false,
            onTap: () => Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => ChatScreen(
                    receiver: contact,
                  ),
                )),
            title: Text(
              (contact != null ? contact.name : null) != null
                  ? contact.name
                  : "..",
              style: TextStyle(
                  color: Colors.white, fontFamily: "Arial", fontSize: 19),
            ),
            subtitle: LastMessageContainer(
              stream: _chatMethods.fetchLastMessageBetween(
                senderId: userProvider.getUser.uid,
                receiverId: contact.uid,
              ),
            ),
            leading: Container(
              constraints: BoxConstraints(maxHeight: 60, maxWidth: 60),
              child: Stack(
                children: <Widget>[
                  CachedImage(
                    contact.profilePhoto,
                    radius: 80,
                    isRound: true,
                  ),
                  OnlineDotIndicator(
                    uid: contact.uid,
                  ),
                ],
              ),
            ),
            trailing: Column(children: <Widget>[
              Row(children: <Widget>[
                isread
                    ? Container()
                    : Icon(Icons.brightness_1, color: Colors.red[400], size: 15)
              ]),
            ]));
      },
    );
  }
}
///这是您的小部件及其构造函数
类ViewLayout扩展了StatefulWidget{
最终用户联系;
视图布局({
@需要这个。联系,
});
@凌驾
State createState()=>_ViewLayoutState();
}
//这是小部件的状态
类_ViewLayoutState扩展状态{
final ChatMethods_ChatMethods=ChatMethods();
布尔伊斯雷德;
地图聊天列表;
@凌驾
小部件构建(构建上下文){
最终用户提供者UserProvider=Provider.of(上下文);
FirebaseUser用户;
if(聊天列表!=null){
if(chatlist['senderId']==user.uid){
//setState通知小部件其状态已更改。在这些通知中,小部件将重建自身
设置状态(){
isread=true;
});
}否则{
设置状态(){
//说出“聊天列表['isread']==null”的最快方法?true:chatlist['isread']]
isread=chatlist['isread']??真;
});
}
}
返回流生成器(
生成器:(上下文,异步快照){
if(snapshot.hasData){
var docList=snapshot.data.documents;
if(docList.isNotEmpty){
}否则{
返回中心(
子对象:CircularProgressIndicator(),
);
}
}
返回自定义磁砖(
迷你:fals