【问题标题】:Correcting Null Safety issue with StreamBuilder in Flutter app在 Flutter 应用程序中使用 StreamBuilder 更正 Null 安全问题
【发布时间】:2021-10-04 10:08:23
【问题描述】:

我的 Flutter 应用中的 StreamBuilder 存在 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'] ?? "";
          }
),

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

我真的很感激这里的一些帮助。

【问题讨论】:

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


    【解决方案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. 只返回一个空的小部件(不是一个很好的做法):
    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");
      },
    ),
    

    【讨论】:

    • 感谢您指出这一点。我不知道也不记得我需要退货。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2021-06-21
    • 2020-06-26
    • 1970-01-01
    • 2018-04-30
    • 2021-11-09
    相关资源
    最近更新 更多