【问题标题】:How to parse dynamic JSON with Flutter?如何用 Flutter 解析动态 JSON?
【发布时间】:2021-12-18 05:03:33
【问题描述】:

我不明白如何解析从 firebase 获得的 JSON 文件。

这是 JSON 文件的格式

{
  "water" : {
    "-MnRJkFC3--ZOTmpF1xN" : {
      "milliliters" : 0.14,
      "time" : "16:26:25"
    },
    "-MnRJkZRwZYEInHfSKIY" : {
      "milliliters" : 48.83,
      "time" : "16:26:25"
    },
    "-MnRJksES18hY765rxxq" : {
      "milliliters" : 41.44,
      "time" : "16:26:25"
    },
    "-MnRJlDn6o4RmiGRJS-E" : {
      "milliliters" : 11.37,
      "time" : "16:26:25"
    }
  }
}

这就是我读取 JSON 文件的方式

Future loadSalesData() async {
  final String jsonString = await getJsonFromFirebase();
  final dynamic jsonResponse = json.decode(jsonString);
  for (Map<String, dynamic> i in jsonResponse)
    chartData.add(SalesData.fromJson(i));
  }

getJsonFromFirebase() 看起来像这样:

Future<String> getJsonFromFirebase() async {
  String url =
      "https://emailpassword. . .seio.com/water.json";
  http.Response response = await http.get(Uri.parse(url));
  return response.body;
}

当您单击链接时,它会将您发送到如下所示的 JSON 文件

{
    "-Mnbk2ye2P8bfpaQvNaU": {
        "milliliters": 0.0,
        "time": "18:07:00"
    },
    "-Mnbk6wd-wJze8P0JknK": {
        "milliliters": 0.12,
        "time": "18:07:00"
    },
    "-Mnbk7Ek629vgBu-MiLg": {
        "milliliters": 44.91,
        "time": "18:07:00"
    },
    "-Mnbk7bPuzqwsz9d5nm6": {
        "milliliters": 5.43,
        "time": "18:07:00"
    },
    "-Mnbk7v7MADi7YzEbeFI": {
        "milliliters": 24.54,
        "time": "18:07:00"
    },
    "-Mnbk8DGfqswckdsA1qP": {
        "milliliters": 47.58,
        "time": "18:07:00"
    },
    "-Mnbk8Xw2kJPxLrqCl6h": {
        "milliliters": 13.98,
        "time": "18:07:00"
    }
}

我得到错误

_InternalLinkedHashMap' 不是“Iterable”类型的子类型

【问题讨论】:

  • getJsonFromFirebase 长什么样子?
  • 嗨弗兰克,这就是 getJsonFromFirebase 的样子 Fu​​ture getJsonFromFirebase() async { String url = "emailpass. . . .firebaseio.com/water.json"; http.Response 响应 = 等待 http.get(Uri.parse(url));返回响应.body; } 该链接将您发送到我的实时数据库中的 JSON 文件
  • 当您点击链接时,JSON 文件看起来像这样 {"-Mnbk2ye2P8bfpaQvNaU":{"milliliters":0.0,"time":"18:07:00"},"-Mnbk6wd-wJze8P0JknK ":{"毫升":0.12,"时间":"18:07:00"},"-Mnbk7Ek629vgBu-MiLg":{"毫升":44.91,"时间":"18:07:00"}," -Mnbk7bPuzqwsz9d5nm6":{"毫升":5.43,"时间":"18:07:00"},"-Mnbk7v7MADi7YzEbeFI":{"毫升":24.54,"时间":"18:07:00"}," -Mnbk8DGfqswckdsA1qP":{"毫升":47.58,"时间":"18:07:00"},"-Mnbk8Xw2kJPxLrqCl6h":{"毫升":13.98,"时间":"18:07:00"}}

标签: json firebase flutter dart firebase-realtime-database


【解决方案1】:

根据您收到的 JSON 格式,json.decode 将返回一个Map&lt;String, dynamic&gt;(更具体地说是_InternalLinkedHashMap&lt;String, dynamic&gt; 专业化的一个实例)。此类型未实现 Iterable,因此您无法使用 for-in 构造直接对其进行迭代,而这正是您在运行时遇到的确切错误。

根据构建SalesData 实例所需的内容,您有两种选择:

  • 迭代entries 属性,如果您需要每个项目的key"-Mnbk2ye2P8bfpaQvNaU""-Mnbk6wd-wJze8P0JknK" 等),否则
  • 如果不这样做,请遍历 values 属性

参赛作品

迭代:
for (MapEntry<String, dynamic> i in jsonResponse.entries) {
  chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson:
SalesData.fromJson(MapEntry<String, dynamic> data) {
  id = data.key;
  milliliters = data.value['milliliters'];
  time = data.value['time'];
}

价值观

迭代:
for (Map<String, dynamic> i in jsonResponse.values) {
  chartData.add(SalesData.fromJson(i));
}
SalesData.fromJson:
SalesData.fromJson(Map<String, dynamic> data) {
  milliliters = data['milliliters'];
  time = data['time'];
}

类型推断

此外,无论您决定如何迭代 Map 实例,您都可以利用 Dart 的 type inference 稍微清理代码,因此(假设您正在迭代条目)loadSalesData 可能变为:

Future loadSalesData() async {
  final jsonString = await getJsonFromFirebase();
  final jsonResponse = json.decode(jsonString);

  for (final i in jsonResponse.entries) {
    chartData.add(SalesData.fromJson(i));
  }
}

getJsonFromFirebase 可能变成:

Future<String> getJsonFromFirebase() async {
  final url = "http://localhost:8080/data.json";
  final response = await http.get(Uri.parse(url));
  return response.body;
}

【讨论】:

  • 非常感谢,写的很详细,帮助很大
【解决方案2】:

似乎flutter 不理解jsonResponseiterable,因为您将其定义为dynamic

调整定义告诉flutter它是一张地图:

final Map<String, dynamic> jsonResponse = json.decode(jsonString);

【讨论】:

  • 非常感谢,这对我有帮助
  • 这完全是错误的。它所做的只是将错误从运行时错误(如上)更改为编译时错误,因为现在编译器知道类型不是Iterable。你真的试过@Nairobi 或@Canada2000 吗?
  • 是的,我确实尝试过,我只需要更改 For 循环,它就能够从 firebase 获取 JSON 文件
  • @msbit 我还按照您的指示更改了我的代码,并且效果很好。
猜你喜欢
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 2019-12-27
  • 1970-01-01
  • 2020-10-13
相关资源
最近更新 更多