0

我正在使用 Firestore,并尝试通过 Streambuilder 获取流。但是,发生了此错误。

The following NoSuchMethodError was thrown building StreamBuilder<DocumentSnapshot<Object>> 
(dirty, state: _StreamBuilderBaseState<DocumentSnapshot<Object>, 
AsyncSnapshot<DocumentSnapshot<Object>>>#32fdb):
The method 'data' was called on null.
Receiver: null
Tried calling: data()

这是我的代码。

    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:flutter/material.dart';
    
    class UserDetailPage extends StatefulWidget {
      String uid;
      UserDetailPage(this.uid);
    
      @override
      _UserDetailPageState createState() => _UserDetailPageState();
    }
    
    class _UserDetailPageState extends State<UserDetailPage> {
      final List<String> datas = <String>['a', 'b', 'c', 'd', 'e', 'f', 'g', '1', '2','3', '4', '5', '6'];
      CollectionReference userstream = FirebaseFirestore.instance.collection('users');
    
      @override
      void initState() {
        super.initState();
    
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('User Detail'),
          ),
          body:_buildBody(),
        );
      }
    
     _buildBody() {
    
        return StreamBuilder(
          stream: userstream.doc(widget.uid).snapshots(),
          builder: (context, snapshot){
            Map<String, dynamic> user_data =snapshot.data.data();
            if(snapshot.hasError){
              return Text('ERROR');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            }
    
            return Padding(
              padding: const EdgeInsets.all(20.0),
              child: ListView.separated(
                padding: EdgeInsets.only(left: 20, right: 20),
                itemCount: 13,
                separatorBuilder: (BuildContext context, int index) => const Divider(),
                itemBuilder: (BuildContext context, int index){
                  return Center(
                    child: Container(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          Text(datas[index]),
                          Text(user_data[datas[index]] is int?user_data[datas[index]].toString():user_data[datas[index]])
                        ],
                      ),
                    ),
                  );
                }
              )
            );
          },
        );
      }
    }

有趣的是,发生此错误后,我想要的结果立即出现在应用程序上。所以我认为问题出现在 initstate() 中,但我不知道到底出了什么问题。

顺便说一下,这个页面是从

UserDetailPage( doc.get('uid')!=null?doc.get('uid'):'5AJUsH5LYaQcBiTtO5MA7d6OKx72');
4

1 回答 1

0

AsyncSnapshot包装异步加载的数据。snapshot.data在不检查数据是否可用的情况下调用(就像您在下面的代码中所做的那样),意味着您忽略了这个事实并且最好不要使用StreamBuilder

  stream: userstream.doc(widget.uid).snapshots(),
  builder: (context, snapshot){
    Map<String, dynamic> user_data =snapshot.data.data();

处理流的正确方法显示在 FlutterFire 文档 on realtime listeners中。您需要进行的更改是您只在所有检查snapshot.data 之后调用,而不是在它们之前调用:

  builder: (context, snapshot){
    if(snapshot.hasError){
      return Text('ERROR');
    }
    if (snapshot.connectionState == ConnectionState.waiting) {
      return Center(child: CircularProgressIndicator());
    }
    Map<String, dynamic> user_data =snapshot.data.data();
  
于 2021-11-03T18:25:43.787 回答