在 Flutter 应用程序中使用 StreamBuilder 更正空安全问题

时间:2021-07-28 16:37:19

标签: flutter stream-builder dart-null-safety

我的 Flutter 应用程序中的 StreamBuilder 存在空安全问题。

在 builder: property 的左括号“{”上,我收到此错误 正文可能会正常完成,导致返回 'null',但返回类型可能是不可为 null 的类型。

这是 StreamBuilder 的代码。

StreamBuilder (
        stream: _db.collection('agency').doc(globals.agencyId).
        collection('trxns').doc(globals.currentTrxnId).snapshots(),
        builder: (BuildContext context, AsyncSnapshot trxnSnapshot) {
          if (trxnSnapshot.hasData) {
            var outPut = (trxnSnapshot.data() as QueryDocumentSnapshot);
            clientFNameController.text = trxnSnapshot.data.data['clientFName'] ?? "";
          }
),

我尝试添加这样的类型:StreamBuilder ( 但我收到此错误:无法将参数类型 'Stream>>' 分配给参数类型 'Stream>?'。

现在我更改类型以匹配上面的语句,现在我又回到了原始错误消息。这是我将类型更改为的内容。

StreamBuilder <DocumentSnapshot<Map<String, dynamic>>>(
        stream: _db.collection('agency').doc(globals.agencyId).
        collection('trxns').doc(globals.currentTrxnId).snapshots(),
        builder: (BuildContext context, AsyncSnapshot trxnSnapshot) {
          if (trxnSnapshot.hasData) {
            var outPut = (trxnSnapshot.data() as QueryDocumentSnapshot);
            clientFNameController.text = trxnSnapshot.data.data['clientFName'] ?? "";
          }
),

我不知道出了什么问题或如何解决。我知道我需要这个“!”或这个 ”?”但我不知道该放哪一个或放在哪里。

我真的很感谢这里的帮助。

1 个答案:

答案 0 :(得分:1)

StreamBuilder 必须在其 builder 参数中返回一个小部件。如果您不需要显示任何小部件(只需进行一些后台更新),您可以使用 StreamSubscription 代替:

class _MyWidgetState extends State<MyWidget> {
  late final StreamSubscription<DocumentSnapshot> _subscription;
 
  @override
  void initState() {
    super.initState();
  
    final Stream<DocumentSnapshot> stream = _db
        .collection('agency')
        .doc(globals.agencyId)
        .collection('trxns')
        .doc(globals.currentTrxnId)
        .snapshots();

    _subscription = stream.listen((data) {
      if (data == null) return;
      setState(() => clientFNameController.text = data['clientFName'] ?? "");
    });
  }

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }
}

但是,如果您想继续使用 StreamBuilder,您可以

  1. 只返回一个空的 Widget(不是一个好的做法):
StreamBuilder(
  stream: _db
      .collection('agency')
      .doc(globals.agencyId)
      .collection('trxns')
      .doc(globals.currentTrxnId)
      .snapshots(),
  builder: (BuildContext context, AsyncSnapshot trxnSnapshot) {
    if (trxnSnapshot.hasData) {
      var outPut = (trxnSnapshot.data as QueryDocumentSnapshot);
      clientFNameController.text = outPut.data['clientFName'] ?? "";
    }
    return SizedBox.shrink();
  },
),
  1. 根据每个操作返回一个有意义的 Widget:
StreamBuilder(
  stream: _db
      .collection('agency')
      .doc(globals.agencyId)
      .collection('trxns')
      .doc(globals.currentTrxnId)
      .snapshots(),
  builder: (BuildContext context, AsyncSnapshot trxnSnapshot) {
    if (trxnSnapshot.hasData) {
      var outPut = (trxnSnapshot.data as QueryDocumentSnapshot);
      clientFNameController.text = outPut.data['clientFName'] ?? "";
      return Text("client name updated");
    }
    return Text("client name not updated");
  },
),