Flutter集成Firebase数据库遇空安全错误求助
解决Flutter Firebase Database的空安全错误
错误原因
你遇到的两个编译错误都是Dart空安全机制的约束导致:
"The property 'snapshot' can't be unconditionally accessed because the receiver can be 'null'."
"The method '[]' can't be unconditionally invoked because the receiver can be 'null'."
StreamBuilder返回的snapshot.data、snapshot.data.snapshot.value都可能为null,直接链式访问会触发编译检查。另外你的代码还存在键名不一致的问题(写入时键名带空格,读取时不带),会导致实际运行时读不到数据。
修复方案
- 显式处理空值并提取数据:在布局渲染前,先提取Firebase返回的快照数据,转为非空类型,避免重复的空判断;
- 统一读写的键名:将写入和读取的键名保持一致,去掉不必要的空格;
- 类型转换:将
dynamic类型的数值转为字符串,适配Text组件的要求。
修改后的完整代码
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class IOTScreen extends StatefulWidget { const IOTScreen({Key? key}) : super(key: key); @override _IOTScreenState createState() => _IOTScreenState(); } class _IOTScreenState extends State<IOTScreen> { bool value = false; bool values = false; final dbRef = FirebaseDatabase.instance.ref(); @override void initState() { super.initState(); initializeFirebase(); } void initializeFirebase() async { try { await Firebase.initializeApp(); print('Firebase initialized successfully'); } catch (e) { print('Failed to initialize Firebase: $e'); } } void onUpdate() { setState(() { value = !value; }); } void onUpdate2() { setState(() { values = !values; }); } void writeData() { // 统一键名,去掉末尾空格 dbRef.child("Data").set({"Humidity:": 0, "Temperature:": 0}); dbRef.child("LightStates").set({"switch": !value}); } void writeData2() { dbRef.child("FanStates").set({"switch": !values}); } @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); return Scaffold( body: StreamBuilder( stream: dbRef.child("Data").onValue, builder: (context, snapshot) { // 先判断数据存在且无错误 if (snapshot.hasData && !snapshot.hasError) { // 显式转换为非空的DatabaseEvent final databaseEvent = snapshot.data! as DatabaseEvent; // 将快照值转为Map,判断非空后再渲染 final dataMap = databaseEvent.snapshot.value as Map<dynamic, dynamic>?; if (dataMap != null) { return Column( children: [ Padding( padding: const EdgeInsets.all(18), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon(Icons.clear_all, size: 30), Text( "Egg Incubator", style: TextStyle( fontSize: 30, fontWeight: FontWeight.bold), ), Icon(Icons.settings, size: 30) ], ), ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text( "Temperature", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), Padding( padding: const EdgeInsets.all(8.0), child: Text( // 读取统一后的键,并转为字符串 dataMap["Temperature:"].toString(), style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ) ], ) ], ), SizedBox(height: 20), Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text( "Humidity", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), Padding( padding: const EdgeInsets.all(8.0), child: Text( dataMap["Humidity:"].toString(), style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ) ], ), SizedBox( height: 60, ), FloatingActionButton.extended( onPressed: () { writeData(); onUpdate(); }, label: value ? Text("Lamp ON") : Text("Lamp OFF"), elevation: 20, backgroundColor: value ? Colors.yellow : Colors.white60, icon: value ? Icon(Icons.wb_incandescent) : Icon(Icons.wb_incandescent_outlined)), SizedBox( height: 60, ), FloatingActionButton.extended( onPressed: () { onUpdate2(); writeData2(); }, label: values ? Text("Fan OFF") : Text("Fan ON"), elevation: 20, backgroundColor: values ? Colors.white60 : Colors.blueAccent, icon: values ? Icon(Icons.wind_power_rounded) : Icon(Icons.wind_power_outlined), ) ], ); } } return Container(); }, ), ); } }
内容的提问来源于stack exchange,提问作者NyK
相关产品推荐
相关产品推荐

