英文:
Getting firebase Realtime database value in syncfusion_flutter_gauges but getting error using stream builder
问题
我目前正在开发一个应用程序,在其中从Firebase实时数据库中获取值并将其放入Syncfusion Flutter仪表中,但一直在遇到错误。尝试从Firebase实时数据库获取数据,。请告诉我如何解决这个问题?这是我的代码:
class MyApp extends StatelessWidget {
final databaseReference = FirebaseDatabase.instance.ref();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: StreamBuilder<DatabaseEvent>(
stream: databaseReference.child('test').child('gasValue').onValue,
builder: (context, snapshot) {
if (snapshot.hasData) {
Object? value = snapshot.data!.snapshot.value;
return SfRadialGauge(
axes: [
RadialAxis(
minimum: 0,
maximum: 100,
showLabels: false,
showTicks: false,
axisLineStyle: AxisLineStyle(
thickness: 0.1,
cornerStyle: CornerStyle.bothCurve,
color: Colors.grey,
thicknessUnit: GaugeSizeUnit.factor,
),
pointers: const [
NeedlePointer(
value: value, //在这里出现错误....!
needleLength: 0.7,
needleColor: Colors.red,
needleStartWidth: 1,
needleEndWidth: 5,
knobStyle: KnobStyle(
knobRadius: 0.09,
sizeUnit: GaugeSizeUnit.factor,
),
),
],
annotations: [
GaugeAnnotation(
widget: Text(
value.toString(),
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
angle: 90,
positionFactor: 0.5,
),
],
),
],
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return CircularProgressIndicator();
}
},
),
),
),
);
}
}
请帮助..! 1: https://i.stack.imgur.com/vUhO1.png
英文:
I am currently working on an app in which I take value from firebase realtime database an put it in syncfusion_flutter_gauges for radial gauge meter but keep getting error.
trying to fetch data from firebase realtime database,
Please tell me how to solve this?
this is my code:
class MyApp extends StatelessWidget {
final databaseReference = FirebaseDatabase.instance.ref();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: StreamBuilder<DatabaseEvent>(
stream: databaseReference.child('test').child('gasValue').onValue,
builder: (context, snapshot) {
if (snapshot.hasData) {
Object? value = snapshot.data!.snapshot.value;
return SfRadialGauge(
axes: [
RadialAxis(
minimum: 0,
maximum: 100,
showLabels: false,
showTicks: false,
axisLineStyle: AxisLineStyle(
thickness: 0.1,
cornerStyle: CornerStyle.bothCurve,
color: Colors.grey,
thicknessUnit: GaugeSizeUnit.factor,
),
pointers: const [
NeedlePointer(
value: value, //getting error here....!
needleLength: 0.7,
needleColor: Colors.red,
needleStartWidth: 1,
needleEndWidth: 5,
knobStyle: KnobStyle(
knobRadius: 0.09,
sizeUnit: GaugeSizeUnit.factor,
),
),
],
annotations: [
GaugeAnnotation(
widget: Text(
value.toString(),
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
angle: 90,
positionFactor: 0.5,
),
],
),
],
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return CircularProgressIndicator();
}
},
),
),
),
);
}
}
Please Help..!
答案1
得分: 1
你将value
定义为Object?
,但在NeedlePointer
小部件中,value
很可能是int
类型。根据你的代码,我猜想从数据库返回的value
可能是int
类型或Map<String, dynamic>
类型。因此,你需要通过将返回的结果强制转换为int
或Map<String, dynamic>
来处理它,例如:
final value = snapshot.data!.snapshot.value! as int;
你确实应该测试一下返回值是否为null
,否则如果它为null
,在.value!
上运行时会导致运行时错误。
最后,你应该将流分配给一个变量,要么在initState
中(这意味着你需要将这个小部件设置为Stateful
小部件),要么在声明时将其用作stream
参数。否则,每次页面重建时都会重新创建这个流。
基于评论的更新:
build
方法可能会因为各种原因运行多次。每次运行时,你的代码中的流将被重新初始化,并重新加载已经存在的数据库数据,而不是像你打算的那样只加载新的数据库事件。
为了避免这种情况,你应该创建一个变量,如下所示,然后将该变量用作你的流值:
final streamVar = databaseReference.child('test').child('gasValue').onValue;
希望这对你有所帮助。
英文:
You are defining value
as Object?
but in the NeedlePointer widget value
is most likely of type int
. From your code and not seeing your database structure, I would guess that the value
returned from the database is either of type int
or of type Map<String, dynamic>
. You therefore need to treat it as such by e.g. casting the returned result to int
or Map<String, dynamic>
using as
.
For example:
final value = snapshot.data!.snapshot.value! as int;
You should really also be testing for the returned value not being null, or your will get a runtime error on the `.value!' if it is.
Finally, you should be assigning your stream to a variable either in initState (means you need this to be a Stateful widget) or declaring it with the stream contents, and using that variable as the stream:
parameter. Otherwise, you are recreating this stream everytime the page rebuilds.
Update based on comment...
The build method can run many times for many reasons. Each time it runs, the stream in your code will be reinitialized and will reload data from the database that you already have, instead of it just loading new database events, as you intend it to do.
To avoid this you should create a variable as follows and then use the variable as your stream value...
final streamVar = databaseReference.child('test').child('gasValue').onValue;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论