You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:05:21