【问题标题】:Flutter Expanded throwing error when waiting for data from Firestore等待来自 Firestore 的数据时,Flutter Expanded 抛出错误
【发布时间】:2019-04-30 12:59:21
【问题描述】:

我从 Firestore 返回的数据有问题。我需要使用Cloud Firestore Plugin 收到一些电子邮件:

class _EmailPageState extends State<EmailPage> {
  //StreamBuilder<QuerySnapshot> _emails;

  @override
  void initState() {
    super.initState();
    //_emails = _getEmails();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Refer user'),
      ),
      body: Column(
    children: <Widget>[
      Form(... form code)
      Expanded(child: _getEmails()),
      ],
    )
}

由于在数据从 Firestore 返回之前不会填充 _emails,因此我得到:

flutter: The following assertion was thrown building Expanded(flex: 1, dirty):
flutter: A build function returned null.
flutter: The offending widget is: Expanded(flex: 1)
flutter: Build functions must never return null. To return an empty space that causes the building widget to
flutter: fill available room, return "new Container()". To return an empty space that takes as little room as
flutter: possible, return "new Container(width: 0.0, height: 0.0)".

我不明白如何解决这个错误。视图显示正确。但我不想出现错误。

 StreamBuilder<QuerySnapshot> _getEmails() {
    final query = Firestore.instance
        .collection('emails')
        .where("referer", isEqualTo: uid)
        .snapshots();

    return StreamBuilder<QuerySnapshot>(
      stream: query,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) return Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return Text('Loading...');
          default:
            return _makeList(snapshot);
        }
      },
    );

    //setState(() {
      //_emails = emailList;
    //});

    //return emailList;
  }

  ListView _makeList(AsyncSnapshot<QuerySnapshot> snapshot) {
    return ListView(
      children: snapshot.data.documents.map((DocumentSnapshot document) {
        return ListTile(
          title: Text(document['email']),
        );
      }).toList(),
    );
  }

【问题讨论】:

    标签: flutter google-cloud-firestore


    【解决方案1】:

    您的 _getEmails() 在数据到达之前返回 null。它应该返回类似CircularProgressIndicator() 的东西。如果您显示该功能,您可以获得更多帮助,但您也可以使用此处的示例代码:https://docs.flutter.io/flutter/widgets/StreamBuilder-class.html

    编辑:好的,我看到了您的编辑。我想它毕竟不会返回 null 。但是,Expanded 必须是 RowColumn 的子代。您应该使用其中之一来包装它,或者使用ContainerCenter 等来进行定位。

    另外,没有必要缓存StreamBuilder,你不应该缓存小部件。但是,您可以缓存流。您至少应该将代码更改为类似

    class _EmailPageState extends State<EmailPage> {
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Refer user'),
          ),
          body: Center(child: _getEmails())
        )
      }
    }
    

    【讨论】:

    • 好吧...也许我应该添加更多代码。我遗漏了一些东西。如果我不使用Expanded,则小部件不会呈现。请查看我的编辑。
    • 感谢您提供有关缓存的提示...我已将其删除。
    • 我看不到构建函数在哪里返回 null... 你可以试试这个:在你的 _makeList 函数中,看看 snapshot.data.documents.isEmpty 是否为真。也许 ListView 有一个空列表,谁知道呢。
    • 我会的。谢谢你。你提到我可以缓存流而不是StreamBuilder。我该怎么做。可以举个例子吗?
    • 当然,这是FutureBuilder 的一个示例:stackoverflow.com/a/52249579/679553 他在initState 中创建Future 并将其放入类中的一个字段中。后来他在FutureBuilder 中使用它。这样您就可以确定相同的Future 实例将可用于FutureBuilder,这将防止一些不需要的重建。您可以对StreamStreamBuilder 执行相同的操作。
    猜你喜欢
    • 1970-01-01
    • 2023-01-27
    • 2020-07-02
    • 2018-12-20
    • 2018-10-25
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 2020-05-06
    相关资源
    最近更新 更多