I've been struggling a lot with this, not able to parse the data from my firebase realtime database using the following code. I have tried everything but I cannot do so. Below is code of necessary files. I'm using provider for state management.
My Firebase Realtime DB: Consist of 2 documents, 1 contains List of object as you can see, 2nd is just a single object.

My Provider code:
class StockProvider with ChangeNotifier {
List<ChartHistoricalData> _histChartData = [];
List<ChartHistoricalData> get histChartData => _histChartData;
Future<void> fetchHistoricalStockData(ref) async {
ref.once().then((DataSnapshot data) {
print(data.value['SBIN_Historical']);
_histChartData = List<ChartHistoricalData>.from(data
.value['SBIN_Historical']
.map((x) => ChartHistoricalData.fromJson(x as Map<String, dynamic>)));
notifyListeners();
});
}
}
The widget where I call:
class _SBINChartState extends State<SBINChart> {
final fb = FirebaseDatabase.instance;
@override
Widget build(BuildContext context) {
final ref = fb.reference();
context.read<StockProvider>().fetchHistoricalStockData(ref);
...
My Model Class:
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']);
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;
}
}
I'm getting the following error:
Reloaded 1 of 620 libraries in 1,111ms.
I/flutter (32700): [{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 (32700): [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:15
E/flutter (32700): #1 MappedListIterable.elementAt (dart:_internal/iterable.dart:412:31)
E/flutter (32700): #2 ListIterator.moveNext (dart:_internal/iterable.dart:341:26)
E/flutter (32700): #3 new List.from (dart:core-patch/array_patch.dart:40:17)
E/flutter (32700): #4 StockProvider.fetchHistoricalStockData.<anonymous closure>
package:algoguru/providers/stock_provider.dart:13
E/flutter (32700): <asynchronous suspension>
E/flutter (32700): #5 StockProvider.fetchHistoricalStockData
package:algoguru/providers/stock_provider.dart:11
E/flutter (32700): <asynchronous suspension>
E/flutter (32700):
If anyone could help, I would really appreciate it, it's been long debugging...
Okay so finally! It is not a great solution but it did work for me. I don't know and i'm not sure about the data type which firebase_database return us, but by first json encoding snapshot instance data and then json decoding it solved the data type issue. The Code:
Future<void> fetchHistoricalStockData(ref) async {
return ref.once().then((DataSnapshot data) {
final cleanup = jsonDecode(jsonEncode(data.value)); // THIS IS THE ANSWER
_histChartData = List<ChartHistoricalData>.from(cleanup['SBIN_Historical']
.map((x) => ChartHistoricalData.fromJson(x as Map<String, dynamic>)));
notifyListeners();
});
}
You can cast the data.value to a Map<String, dynamic> and use it in the fetchHistoricalStockData method like below:
Future<void> fetchHistoricalStockData(ref) async {
ref.once().then((DataSnapshot data) {
Map<String, dynamic> dataValue = data.value as Map<String, dynamic>;
_histChartData = List<ChartHistoricalData>.from(dataValue['SBIN_Historical']
.map((x) => ChartHistoricalData.fromJson(x as Map<String, dynamic>)));
notifyListeners();
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With