我在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
的第一个键的变量,但由于某种原因,在开始时没有值。这是问题的根源。请帮助我。我不知道该怎么做。
2条答案
按热度按时间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
中,您的代码应该如下所示:lawou6xi2#
只需改变位置并添加新条件,如下所示