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

如何在Flutter中从指定JSON数据中获取folderName字段值?

问题描述

在Flutter中编写_chooseFolder方法时,无法从Firebase Realtime Database的快照数据中正确获取folderName字段值。相关信息如下:

尝试代码

Future<void> _chooseFolder() async {
    final snapshot = await ref.get();
    if (snapshot.exists) {
      print(snapshot.value);
      var v = Map<String, dynamic>.from(snapshot.value as Map);
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
                title: Text('Choose folder'),
                content: Container(
                  height: 300.0,
                  width: 300.0,
                  child: ListView.builder(
                    shrinkWrap: true,
                    itemCount: snapshot.children.length,
                    itemBuilder: (BuildContext context, int index) {
                      return ListTile(
                        title: v['folderName'],
                      );
                    },
                  ),
                ));
          });
    } else {
      print('No data available.');
    }
  }

获取到的JSON数据

{-NKKEkzjOLaHqdmZSQQN: {folderName: test 8}, -NKKEb1eMBmOyhVdQA8b: {folderName: test 6}, -NKKGCxwDJngEjJG5bDQ: {folderName: test 9}, -NKKEfUoygYzFWH-2PbU: {folderName: test 7}}

数据库层级结构

unique_user_id
   -folders
      - -NKKEkzjOLaHqdmZSQQN
           -folderName: "test"

其中-NKKEkzjOLaHqdmZSQQN为Firebase自动生成的键。


解决方案

问题核心是未正确遍历Firebase快照的子节点:顶层Map的键是自动生成的ID,folderName字段存在于每个ID对应的子Map中,直接从顶层Map取值自然无法获取。

以下两种修正方式任选其一:

方式一:遍历快照的children节点

直接通过snapshot.children访问每个子节点快照,从中提取folderName:

Future<void> _chooseFolder() async {
  final snapshot = await ref.get();
  if (snapshot.exists) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Choose folder'),
          content: Container(
            height: 300.0,
            width: 300.0,
            child: ListView.builder(
              shrinkWrap: true,
              itemCount: snapshot.children.length,
              itemBuilder: (BuildContext context, int index) {
                final childSnapshot = snapshot.children.elementAt(index);
                final folderName = (childSnapshot.value as Map)['folderName'];
                return ListTile(
                  title: Text(folderName ?? 'Unknown Folder'),
                );
              },
            ),
          ),
        );
      },
    );
  } else {
    print('No data available.');
  }
}

方式二:遍历顶层Map的entries

通过Map操作提取所有folderName到列表后再渲染:

Future<void> _chooseFolder() async {
  final snapshot = await ref.get();
  if (snapshot.exists) {
    final foldersMap = Map<String, dynamic>.from(snapshot.value as Map);
    final folderNames = foldersMap.values.map((folder) => folder['folderName'] as String).toList();
    
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Choose folder'),
          content: Container(
            height: 300.0,
            width: 300.0,
            child: ListView.builder(
              shrinkWrap: true,
              itemCount: folderNames.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  title: Text(folderNames[index] ?? 'Unknown Folder'),
                );
              },
            ),
          ),
        );
      },
    );
  } else {
    print('No data available.');
  }
}

关键注意点

  • Firebase自动生成的ID是顶层节点的键,需深入到子节点才能获取folderName;
  • 添加空值判断(如?? 'Unknown Folder')可避免空指针异常;
  • 使用snapshot.children能直接操作节点快照,无需手动处理Map键值对,代码更直观。

内容的提问来源于stack exchange,提问作者Hammad Nasir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:25:59