无法无条件访问属性“docs”,因为收到的可能是“null” Flutter

时间:2021-03-17 09:25:55

标签: firebase flutter dart dart-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];

3 个答案:

答案 0 :(得分:1)

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

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

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

StreamBuilder<QuerySnapshot>(
  ...
);

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

snapshot.data!.docs.length

答案 1 :(得分:0)

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

      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"]);
                    });
              });
        }

答案 2 :(得分:0)

我通过添加 StreamBuilder 和构建器(上下文、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());
    });
 }