firebase 错误空值Flutter上使用的空检查运算符

vpfxa7rd  于 2023-01-14  发布在  Flutter
关注(0)|答案(2)|浏览(144)

我在StreamBuilder中遇到此错误:

下面是代码:

import 'dart:async';

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';

class NewCauseMenu extends StatefulWidget {
  String? area;
  NewCauseMenu(this.area, {super.key});

  @override
  State<NewCauseMenu> createState() => _NewCauseMenuState();
}

class _NewCauseMenuState extends State<NewCauseMenu> {
  final db = FirebaseDatabase.instance;

  String? dropdownValue;
  String? problem;
  String? causa1;
  String? causa2;
  String? causa3;
  String? causa4;

  var setDefaultProblem = true, setDefaultCauseOne = true;
  @override
  Widget build(BuildContext context) {
    final myRef = db.ref();

    return WillPopScope(
      onWillPop: () {
        return _onWillPopScope();
      },
      child: SafeArea(
          child: Scaffold(
        appBar: AppBar(
          title: Text('Menú Nueva Causa ${widget.area}'),
        ),
        body: Center(
          child: Column(
            children: [
              const SizedBox(
                height: 25,
              ),
              StreamBuilder(
                  stream: myRef.child(widget.area.toString()).onValue,
                  builder: (context, snapshot) {
                    if (!snapshot.hasData) return Container();
                    final data = Map<String, dynamic>.from(
                        (snapshot.data)!.snapshot.value as Map);
                    if (setDefaultProblem) {
                      problem = data.keys.first.toString();
                    }
                    return DropdownButton(
                      value: problem,
                      icon: const Icon(Icons.arrow_downward),
                      isExpanded: false,
                      elevation: 16,
                      underline: Container(
                        height: 2,
                        color: Colors.blueAccent,
                      ),
                      items: data.keys.map(((e) {
                        return DropdownMenuItem(
                            value: e.toString(), child: Text(e.toString()));
                      })).toList(),
                      onChanged: (value) {
                        setState(() {
                          problem = value!;
                          setDefaultProblem = false;
                          setDefaultCauseOne = true;
                        });
                      },
                    );
                  }),
              const SizedBox(
                height: 25,
              ),
              problem != null
                  ? StreamBuilder(
                      stream: myRef
                          .child(widget.area.toString())
                          .child(problem.toString())
                          .onValue,
                      builder: (context, snapshot) {
                        final data = Map<String, dynamic>.from(
                            (snapshot.data!.snapshot.value as Map));
                        if (!snapshot.hasData) {
                          debugPrint('snapshot status: ${snapshot.error}');
                          return Text(
                              'snapshot empty problem: $problem causa #1: $causa1');
                        }

                        debugPrint(data.toString());
                        if (setDefaultCauseOne) {
                          causa1 = data.keys.first.toString();
                        }
                        return DropdownButton(
                          value: causa1,
                          icon: const Icon(Icons.arrow_downward),
                          isExpanded: false,
                          elevation: 16,
                          underline: Container(
                            height: 2,
                            color: Colors.blueAccent,
                          ),
                          items: data.keys.map(((e) {
                            return DropdownMenuItem(
                                value: e.toString(), child: Text(e.toString()));
                          })).toList(),
                          onChanged: (value) {
                            setState(() {
                              causa1 = value!;
                              setDefaultCauseOne = false;
                            });
                          },
                        );
                      },
                    )
                  : Text('problem null problem: $problem causa #1: $causa1')
            ],
          ),
        ),
      )),
    );
  }

  Future<bool> _onWillPopScope() async {
    Navigator.of(context).pop();
    return false;
  }
}

我不知道为什么在第二个StreamBuilder中有一个null值,我在第一个StreamBuilder中定义了变量problem,它应该可以和第二个一起工作,但是它没有。
当我运行程序时,发生了以下情况:

错误发生后,似乎应用程序工作完美。
我验证了变量problem必须得到一个值,否则第二个StreamBuilder不工作。我给了一个值给得到snapshot.data的第一个键的变量,但由于某种原因,在开始时没有值。这是问题的根源。请帮助我。我不知道该怎么做。

aiazj4mn

aiazj4mn1#

当你试图访问一个属性或者调用一个空值对象的方法时,会抛出"空指针"异常。在你的代码中,看起来像是在final data = Map<String, dynamic>.from((snapshot.data!.snapshot.value as Map));行发生的,在那里你试图访问"快照"的"数据"属性。
问题是这样的:在Firebase流中,如果没有接收到数据,那么snapshot.data将为空。因此,如果没有数据,您不应该尝试访问snapshot.data。您可以通过在尝试访问snapshot.data之前添加if (snapshot.data != null)检查来绕过此问题。
因此,在第二个StreamBuilder中,您的代码应该如下所示:

if (!snapshot.hasData) {
   debugPrint('snapshot status: ${snapshot.error}');
   return Text('snapshot empty problem: $problem causa #1: $causa1');
}
final data = Map<String, dynamic>.from((snapshot.data!.snapshot.value as Map));
lawou6xi

lawou6xi2#

只需改变位置并添加新条件,如下所示

if (!snapshot.hasData || snapshot.data == null) {
                          debugPrint('snapshot status: ${snapshot.error}');
                          return Text(
                              'snapshot empty problem: $problem causa #1: $causa1');
                        }
final data = Map<String, dynamic>.from(
                            (snapshot.data!.snapshot.value as Map));

                        debugPrint(data.toString());
                        if (setDefaultCauseOne) {
                          causa1 = data.keys.first.toString();
                        }

相关问题