【问题标题】:A non-null String must be provided to a Text widget flutter?必须向 Text 小部件颤振提供非空字符串?
【发布时间】:2021-03-17 19:04:31
【问题描述】:

我正在尝试检查用户 displayName 在 firebase 中是否为空。它应该导航到他必须输入他的姓名的表格。目前,firebase 中的 displayName 默认为 null。但是我遇到了一个错误。

必须为 Text 小部件提供非空字符串。

'package:flutter/src/widgets/text.dart':

断言失败:第 360 行 pos 10: 'data != null'

Row(
  children: [
    Container(
      margin: EdgeInsets.only(bottom: 50, left: 30),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        //crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Welcome !"),
          // ignore: unrelated_type_equality_checks
          Text(snapshot.data.documents
                      .elementAt(index)['displayName']) !=
                  null
              ? Text(snapshot.data.documents
                  .elementAt(index)['displayName'])
              : Navigator.pushNamed(context, '/UserDetail'),
        ],
      ),
    ),
  ],
),

【问题讨论】:

    标签: firebase flutter


    【解决方案1】:

    试试这个。

    Row(
      children: [
        Container(
          margin: EdgeInsets.only(bottom: 50, left: 30),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            //crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("Welcome !"),
              // ignore: unrelated_type_equality_checks
              snapshot.data.documents.elementAt(index)['displayName'] !=
                      null
                  ? Text(snapshot.data.documents
                      .elementAt(index)['displayName'])
                  : Navigator.pushNamed(context, '/UserDetail'),
            ],
          ),
        ),
      ],
    ),
    

    Text 小部件不会给您null。只有你给的数据可以是null

    【讨论】:

    • 它工作但现在得到了这个。构建时抛出了以下断言:在构建期间调用了 setState() 或 markNeedsBuild()。这个 Overlay 小部件不能被标记为需要构建,因为框架已经在
    • 你在哪里调用 setState?显示你的整个代码
    【解决方案2】:

    你错过了很多。让我们尝试解决这个问题!

    1. 忽略可能的错误是个坏主意。
    2. 永远不要写// ignore: unrelated_type_equality_checks
    3. 您的代码试图做什么?我们需要知道您需要什么。

    你写的有什么问题?

    1. // ignore: 强制 linter 忽略特定类型的问题。您忽略了unrelated_type_equality_checks,这意味着您不认为比较两种不同的数据类型是错误的。这是不好的。 2"someString" 是不同的数据类型。当您比较它们时:2 == "someString" 它永远不会评估为true。永远是false
    2. 你写的实际比较总是正确的。
                  Text(snapshot.data.documents
                          .elementAt(index)['displayName']) !=
                      null
                  ? Text(snapshot.data.documents
                      .elementAt(index)['displayName'])
                  : Navigator.pushNamed(context, '/UserDetail')
    

    这是仅一行的比较:

    Text(snapshot.data.documents.elementAt(index)['displayName']) != null
    

    让我们简化它以显示错误所在。看看为什么比较总是正确的?

    Text('displayName') != null // always true
    

    你可能打算写:(我只是从你写的比较中删除了 Text()。

                  snapshot.data.documents
                          .elementAt(index)['displayName'] !=
                      null
                  ? Text(snapshot.data.documents
                      .elementAt(index)['displayName'])
                  : Navigator.pushNamed(context, '/UserDetail')
    

    但是这段代码仍然没有意义!如果文档的显示名称不为 null,则比较的结果是 Text 小部件。如果显示名称为空,我们调用Navigator.pushNamed,它不是返回Widget 的函数。我们需要三元运算符的两个部分都返回一个Widget,并且只有Text() 部分返回一个Widget。对Navigator.pushNamed 的调用没有返回Widget,这是一个错误。

    以下是解决类型不匹配的方法:

                  snapshot.data.documents
                          .elementAt(index)['displayName'] !=
                      null
                  ? Text(snapshot.data.documents
                      .elementAt(index)['displayName'])
                  : Text("Something went wrong!")
    

    但是在我们修复了三元运算符中的类型不匹配之后,还有另一个问题。我们在重复自己! snapshot.data.documents.elementAt(index)['displayName'] 写了两次! 不要重复自己

                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  name != null
                      ? Text(name)
                      : Text("Something went wrong!")
    

    看看我们如何得到Text Widget 无论如何?我们可以缩短它!

                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  Text(name != null ? name : "Something went wrong!")
    

    这种空值检查非常常见,以至于 Dart 给了一个操作符 ?? 来做它。

                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  Text(name ?? "Something went wrong!")
    

    但是这段代码还是有bug的。

    我必须假设 snapshot 的数据类型为 AsyncSnapshot,因为您的示例不完整。 AsyncSnapshot 可能是错误,也可能是数据。您必须在使用数据之前进行检查!

                  if (snapshot.hasError) return Text("Oops!");
    
                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  Text(name ?? "Something went wrong!")
    

    等待文件到达不是错误。这意味着我们需要检查AsyncSnapshot 是否还有数据!

                  if (snapshot.hasError) return Text("Oops!");
                  if (!snapshot.hasData) return Text("No data yet!");
    
                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  Text(name ?? "Something went wrong!")
    

    太棒了!现在我们确定快照中有数据!但是如果该数据是一个空列表呢?

                  if (snapshot.hasError) return Text("Oops!");
                  if (!snapshot.hasData) return Text("No data yet!");
                  if (snapshot.data.documents.isEmpty) return Text("No documents!");
    
                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  Text(name ?? "Something went wrong!")
    

    但是如果我们在文档列表中只得到一个文档,而 index5 怎么办?那将是RangeError。如果displayName 不在文档中怎么办?那将是KeyError

    如果您确信您的 index 不会太大,并且您的所有文档都有 displayName,请随意忽略可能的错误。

    这是我们解决所有误解后得到的结果。

                  if (snapshot.hasError) return Text("Oops!");
                  if (!snapshot.hasData) return Text("No data yet!");
                  if (snapshot.data.documents.isEmpty) return Text("No documents!");
    
                  var name = snapshot.data.documents.elementAt(index)['displayName'];
                  
                  return Row(
                    children: [
                      Container(
                        margin: EdgeInsets.only(bottom: 50, left: 30),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Text("Welcome !"),
                            Text(name ?? "Something went wrong!")
                          ],
                        ),
                      ),
                    ],
                  );
    

    【讨论】:

      猜你喜欢
      • 2021-02-14
      • 2021-03-03
      • 2021-07-19
      • 2020-04-14
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多