Flutter-Firestore开发问题:设备名称列表构建与设置更新优化
问题解答
问题1:从Firestore查询并映射deviceName为字符串列表
直接修改查询后的映射逻辑,从文档数据中提取deviceName字段即可,同时注意处理空值避免类型错误:
单次查询版本
Future<List<String>> getDeviceNames(String userEmail) async { final querySnapshot = await FirebaseFirestore.instance .collection('devices') .where('userEmail', isEqualTo: userEmail) // 替换为你实际存储用户邮箱的字段名 .get(); return querySnapshot.docs .map((doc) => doc.data()['deviceName'] as String?) .where((name) => name != null) .cast<String>() .toList(); }
实时监听版本(如果需要自动同步数据变化)
Stream<List<String>> deviceNamesStream(String userEmail) { return FirebaseFirestore.instance .collection('devices') .where('userEmail', isEqualTo: userEmail) .snapshots() .map((snapshot) => snapshot.docs .map((doc) => doc.data()['deviceName'] as String?) .where((name) => name != null) .cast<String>() .toList()); }
问题2:避免NumberPicker调整时重复调用函数,仅保存时更新Firestore
核心思路是把设备设置的状态存在本地,仅在必要时读取、仅在点击保存时写入:
class _SettingsPageState extends State<SettingsPage> { String? _selectedDeviceId; int _localStartHour = 0; // 本地存储当前调整的小时数 // 仅在切换设备时调用一次,获取初始设置 Future<void> _loadDeviceSettings(String deviceId) async { final doc = await FirebaseFirestore.instance .collection('devices') .doc(deviceId) .get(); if (doc.exists) { setState(() { _localStartHour = doc.data()?['startHour'] ?? 0; }); } } // 仅点击保存按钮时,将本地状态同步到Firestore Future<void> _saveDeviceSettings() async { if (_selectedDeviceId == null) return; await FirebaseFirestore.instance .collection('devices') .doc(_selectedDeviceId!) .update({'startHour': _localStartHour}); } @override Widget build(BuildContext context) { return Column( children: [ DropdownButton<String>( value: _selectedDeviceId, items: yourDeviceList.map((device) { return DropdownMenuItem( value: device.id, child: Text(device.name), ); }).toList(), onChanged: (newDeviceId) { setState(() { _selectedDeviceId = newDeviceId; }); // 切换设备时才加载初始设置 if (newDeviceId != null) { _loadDeviceSettings(newDeviceId); } }, ), NumberPicker( value: _localStartHour, minValue: 0, maxValue: 23, onChanged: (newHour) { // 仅更新本地状态,不触发任何Firestore操作 setState(() { _localStartHour = newHour; }); }, ), ElevatedButton( onPressed: _saveDeviceSettings, child: const Text('Save Settings'), ), ], ); } }
说明:
- NumberPicker的
onChanged只修改本地状态变量_localStartHour,不会触发任何Firestore的读写 - 仅在Dropdown切换设备时,调用一次
_loadDeviceSettings获取初始的startHour值 - 只有点击「Save Settings」按钮时,才调用
_saveDeviceSettings把本地的小时数同步到Firestore
内容的提问来源于stack exchange,提问作者Johan Scheepers
相关产品推荐
相关产品推荐

