Flutter(Dart)获取Firebase中ESP8266传感器数据时遇'value'未定义错误
错误原因
你遇到的错误是因为Firebase Realtime Database的Flutter SDK更新后,once()方法不再直接返回DataSnapshot,而是返回DatabaseEvent对象。原代码直接访问snapshot.value,但DatabaseEvent没有这个属性,必须先通过它的snapshot属性拿到DataSnapshot,再读取value。
另外代码还有两处问题:
- 在State的构造函数里调用
setState无效,应该用initState生命周期方法处理初始化逻辑 onChildChanged监听中,snap已经是DataSnapshot,不需要重复写snap.snapshot.value,直接用snap.value即可
修正后的代码
bool ledOn = false; bool heaterOn = false; double drunkAmount = 0.0; String temperature = ''; final database = FirebaseDatabase.instance.ref(); @override void initState() { super.initState(); _fetchInitialData(); _setupChildChangedListener(); } void _fetchInitialData() async { final event = await database.child('ESP').once(); final data = event.snapshot.value as Map<String, dynamic>; setState(() { temperature = data['temperature']?.toString() ?? ''; drunkAmount = (data['drunkAmount'] as num?)?.toDouble() ?? 0.0; // 替换成你实际的加热器字段名,比如'heater' heaterOn = (data['heater'] as num?) == 0; ledOn = (data['LED'] as num?) == 0; }); } void _setupChildChangedListener() { database.child('ESP').onChildChanged.listen((event) { final snap = event.snapshot; setState(() { switch(snap.key) { case 'drunkAmount': drunkAmount = (snap.value as num?)?.toDouble() ?? 0.0; break; case 'temperature': temperature = snap.value?.toString() ?? ''; break; case 'LED': ledOn = (snap.value as num?) == 0; break; case 'heater': heaterOn = (snap.value as num?) == 0; break; } }); }); }
关键说明
- 用
initState处理数据初始化和监听注册,这是State组件初始化逻辑的标准位置 - 调用
once()后,通过event.snapshot获取数据快照,再读取value - 加入空安全处理(
?.和??),避免数据为null时触发报错 - 所有UI相关的数据更新必须放在
setState内,确保界面能同步刷新
内容的提问来源于stack exchange,提问作者Kafka
相关产品推荐
相关产品推荐

