【问题标题】:The property 'docs' cannot be unconditionally accessed because received can be 'null' Flutter属性 'docs' 不能无条件访问,因为接收到的可能是 'null' Flutter
【发布时间】:2021-06-14 14:57:48
【问题描述】:

迁移到 null-safety 后显示此错误。我现在该怎么办?

  Widget chatMessages() {
    return StreamBuilder(
        stream: messageStream,
        builder: (context, snapshot) {
          return snapshot.hasData
              ? ListView.builder(
                  padding: EdgeInsets.only(bottom: 70, top: 16),
                  itemCount: snapshot.data.docs.length,
                  reverse: true,
                  itemBuilder: (context, index) {
                    DocumentSnapshot ds = snapshot.data.docs[index];
                    return chatMessageTitle(
                        ds["message"], myUserName == ds["sendBy"]);
                  })
              : Center(child: CircularProgressIndicator());
        });
  }

添加显示此错误的空检查 (!) 后

              itemCount: snapshot.data!.docs.length,
              reverse: true,
              itemBuilder: (context, index) {
                DocumentSnapshot ds = snapshot.data!.docs[index];

【问题讨论】:

  • 嗨! snapshot.data 是什么类型的?可以提供吗

标签: firebase flutter dart dart-null-safety


【解决方案1】:

我通过添加 StreamBuilder 和 builder(context, AsyncSnapshot 快照) 解决了我的问题。

 Widget chatMessages() {
     return StreamBuilder<QuerySnapshot>(
        stream: messageStream,
        builder: (context, AsyncSnapshot snapshot) {
       return snapshot.hasData
          ? ListView.builder(
              padding: EdgeInsets.only(bottom: 70, top: 16),
              itemCount: snapshot.data.docs.length,
              reverse: true,
              itemBuilder: (context, index) {
                DocumentSnapshot ds = snapshot.data.docs[index];
                return chatMessageTitle(
                    ds["message"], myUserName == ds["sendBy"]);
              })
          : Center(child: CircularProgressIndicator());
    });
 }

【讨论】:

    【解决方案2】:

    有几个解决方案:

    • 为您的StreamBuilder 提供一个类型:

      StreamBuilder<QuerySnapshot> (...)
      
    • builder 的第二个参数提供一个类型:

      builder: (context, QuerySnapshot snapshot)
      
    • 使用as 向下转换:

      (snapshot.data! as QuerySnapshot).docs['key']
      

    【讨论】:

      【解决方案3】:

      您必须将snapshot.data 转换为它的类型。假设类型为QuerySnapshot(将其更改为snapshot.data的实际类型)。

      (snapshot.data! as QuerySnapshot).docs.length
      

      我们可以在StreamBuilder 中指定stream 的类型,而不是在所有位置进行类型转换。

      StreamBuilder<QuerySnapshot>(
        ...
      );
      

      现在snapshot.data 被推断为QuerySnapshot 并且不需要类型转换。

      snapshot.data!.docs.length
      

      【讨论】:

        【解决方案4】:

        像这样添加错误和连接状态检查:

              Widget chatMessages() {
                return StreamBuilder(
                    stream: messageStream,
                    builder: (context, snapshot) {
                      if (snapshot.hasError) {
                        return Text('Something went wrong');
                        }
                      if (snapshot.connectionState == ConnectionState.waiting) {
                        return Text("Loading");
                        }
                      return ListView.builder(
                          padding: EdgeInsets.only(bottom: 70, top: 16),
                          itemCount: snapshot.data.docs.length,
                          reverse: true,
                          itemBuilder: (context, index) {
                            DocumentSnapshot ds = snapshot.data.docs[index];
                            return chatMessageTitle(
                            ds["message"], myUserName == ds["sendBy"]);
                            });
                      });
                }
        

        【讨论】:

          猜你喜欢
          • 2021-08-12
          • 2022-08-15
          • 2022-08-20
          • 2022-08-15
          • 2021-09-21
          • 2021-07-13
          • 2022-08-15
          • 1970-01-01
          • 2021-09-16
          相关资源
          最近更新 更多