firebase - 无法使用提供程序 Flutter 设置从 Firebase 数据库获取的数据
问题描述
我正在尝试从我的 fierbase 数据库中获取数据(对象/字典列表),但我无法使用提供程序设置状态。
这是我的 Firebase 数据库结构:
historical_data: [
{key: val, key: val, ...},
{key: val, key: val, ...},
...
],
live_data: {
key: val,
key: val,
...
}
提供者文件:
class StockProvider with ChangeNotifier {
List<ChartHistoricalData> _histChartData = [];
List<ChartHistoricalData> get histChartData => _histChartData;
Future<void> fetchHistoricalStockData(ref) async {
await ref.once().then((DataSnapshot data) {
print(data.value['historical_data']); // Working at this point, I can see my list of objects.
_histChartData = List<ChartHistoricalData>.from(data
.value['SBIN_Historical']
.map((x) => ChartHistoricalData.fromJson(x as Map<String, dynamic>)).toList());
});
notifyListeners();
}
}
我的模型课:
class ChartHistoricalData {
DateTime? x; //DateTime
double? open;
double? high;
double? low;
double? close;
ChartHistoricalData(
{required this.x,
required this.open,
required this.high,
required this.low,
required this.close});
ChartHistoricalData.fromJson(Map<String, dynamic> json) {
x = DateTime.parse(json['date']); //date of type string coming from firebase db
open = json['open'];
high = json['high'];
low = json['low'];
close = json['close'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['date'] = this.x;
data['open'] = this.open;
data['high'] = this.high;
data['low'] = this.low;
data['close'] = this.close;
return data;
}
}
主画面:
class SBINChart extends StatefulWidget {
const SBINChart({Key? key}) : super(key: key);
@override
_ChartState createState() => _ChartState();
}
class _ChartState extends State<Chart> {
final fb = FirebaseDatabase.instance;
@override
Widget build(BuildContext context) {
final ref = fb.reference();
context.read<StockProvider>().fetchHistoricalStockData(ref);
print(context.watch<StockProvider>().histChartData); // Empty
...
错误:
/flutter ( 4730): [{date: 2021-01-01, high: 280.0, low: 274.4, close: 279.4, open: 274.9}, {date: 2021-01-04, high: 283.9, low: 277.75, close: 281.05, open: 281.85}, {date: 2021-01-05, high: 282.45, low: 277.0, close: 281.75, open: 278.05}, {date: 2021-01-06, high: 289.15, low: 281.4, close: 285.05, open: 283.0}, {date: 2021-01-07, high: 291.8, low: 287.0, close: 287.7, open: 289.0}, {date: 2021-01-08, high: 291.4, low: 285.2, close: 286.0, open: 290.1}, {date: 2021-01-11, high: 288.2, low: 279.6, close: 282.5, open: 288.0}, {date: 2021-01-12, high: 293.85, low: 277.9, close: 292.5, open: 280.0}, {date: 2021-01-13, high: 308.0, low: 294.5, close: 306.8, open: 296.0}, {date: 2021-01-14, high: 309.25, low: 303.8, close: 307.25, open: 306.7}, {date: 2021-01-15, high: 310.9, low: 301.3, close: 303.85, open: 306.8}, {date: 2021-01-18, high: 308.65, low: 292.2, close: 294.45, open: 303.5}, {date: 2021-01-19, high: 302.5, low: 296.4, close: 298.6, open: 297.65}, {date: 2021-01-20, high: 304.7, low: 296.85, close: 302.55, open: 298.8
E/flutter ( 4730): [ERROR:flutter/shell/common/shell.cc(103)] Dart Unhandled Exception: type '_InternalLinkedHashMap<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>' in type cast, stack trace: #0 StockProvider.fetchHistoricalStockData.<anonymous closure>.<anonymous closure>
package:algoguru/providers/stock_provider.dart:16
E/flutter ( 4730): #1 MappedListIterable.elementAt (dart:_internal/iterable.dart:412:31)
E/flutter ( 4730): #2 ListIterator.moveNext (dart:_internal/iterable.dart:341:26)
E/flutter ( 4730): #3 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
E/flutter ( 4730): #4 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
E/flutter ( 4730): #5 new List.of (dart:core-patch/array_patch.dart:50:28)
E/flutter ( 4730): #6 ListIterable.toList (dart:_internal/iterable.dart:212:44)
E/flutter ( 4730): #7 StockProvider.fetchHistoricalStockData.<anonymous closure>
package:algoguru/providers/stock_provider.dart:17
E/flutter ( 4730): <asynchronous suspension>
E/flutter ( 4730): #8 StockProvider.fetchHistoricalStockData
package:algoguru/providers/stock_provider.dart:12
E/flutter ( 4730): <asynchronous suspension>
我认为该方法可能有问题ChartHistoricalData.fromJson
,但是由于我是新手,所以我无法弄清楚出了什么问题。如果有人可以提供帮助,那就太好了!
解决方案
在您的提供程序中更改此设置:
.map((x) => ChartHistoricalData.fromJson(x as Map<String, dynamic>)));
仔细阅读您遇到的错误。它告诉你这是一个类型不匹配错误,这意味着它期望某种类型,Map<String, dynamic>
但你有某种类型的东西<Object?, Object?>
。
虽然它们在内部是相同的数据,但只有你知道。飞镖它不知道。dart 是从哪里得到错误object?
以显示给我们的?它来自 Firebase 的软件包。因为他们知道它肯定是一个物体,它可以是任何东西。
但是对于您,您告诉您的方法这些对象将明确地是动态的字符串。否则,抛出一个错误,这正是发生的事情。
这会导致您的错误。我提出的解决方案叫做casting
,你告诉 dart,我们传递的变量 x 将被视为一个Map<String, dynamic>
对象,所以处理它并相应地解析它。
Dart 会说好的,很酷。但是如果它得到的对象不是一个Map<String, dynamic>
对象,它会抛出一个不同的错误,说你所要求的是不可能的,因为演员双方的对象是不同的。
Future<void> fetchHistoricalStockData(ref) async {
await ref.once().then((DataSnapshot data) {
print(data.value['historical_data']); // Working at this point, I can see my list of objects.
_histChartData = List<ChartHistoricalData>.from(jsonDecode(data
.value['SBIN_Historical'])
.map((x) => ChartHistoricalData.fromJson(x as Map<String, dynamic>)).toList());
});
notifyListeners();
}
推荐阅读
- bash - 无法在我的 docker 容器中启动脚本
- angularjs - 如何将 JSON 和图像文件发送到服务器?
- javascript - (节点:31260)UnhandledPromiseRejectionWarning
- laravel - Laravel Image 干预在上传时出现 503 错误
- java - Android RecyclerView:如果不使用“setIsRecyclabe(false)”,则滚动期间内存使用量会增加
- swift - 从 Swift 中的字符串中删除 '
- python - Python:将开始日期和结束日期拆分为开始日期和结束日期之间的所有日期
- javascript - Rxjs 在继续之前等待先前的间隔请求执行
- python - Python中两个矩阵的并集
- smtp - Gerrit 无法发送电子邮件验证消息 504