I created a realtime database on firebase and wanted the data stored to be displayed on flutter but I noticed that whenever I opened the screen meant to display the data stored, after the CircularProgressIndicator for a while, i get an error "type '_Map<Object?, Object?>' is not a subtype of type 'Map<String?, dynamic>' in type cast" printed on the console.
This is my code to display the data from the database.
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
class DailyTipsScreen extends StatefulWidget {
const DailyTipsScreen({Key? key}) : super(key: key);
@override
State<DailyTipsScreen> createState() => _DailyTipsScreenState();
}
class _DailyTipsScreenState extends State<DailyTipsScreen> {
late DatabaseReference tipsRef;
@override
void initState() {
super.initState();
tipsRef = FirebaseDatabase.instance.ref().child('tips');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Tips'),
),
body: StreamBuilder<DatabaseEvent>(
stream: tipsRef.onValue,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
final tips = <Map<String, dynamic>>[];
final dataSnapshot = snapshot.data!.snapshot;
(dataSnapshot.value as Map<String?, dynamic>).forEach((key, value) {
tips.add(value);
});
return ListView.builder(
itemCount: tips.length,
itemBuilder: (context, index) {
final tip = tips[index];
final homeTeamName = tip['home_team_name'];
final awayTeamName = tip['away_team_name'];
final scoreFulltime = tip['score_fulltime'];
final bettingTips = tip['betting_tips'];
final odds = <String>[];
bettingTips.forEach((key, value) {
odds.add(value['odds']);
});
final oddsString = odds.join(' / ');
return ListTile(
title: Text('$homeTeamName vs $awayTeamName'),
subtitle: Text('Score: $scoreFulltime, Odds: $oddsString'),
);
},
);
},
),
);
}
}
My workaround was this cast:
myJson = Map<String, dynamic>.from (snapshot.value as Map);
This doesn't look nice, but I will use this until anything more elegant comes up.
You should cast your data to the type you want. Map<Object?, Object> can be cast to the type you want by the following code:
map.cast<String, dynamic>()
So, you can solve this problem by changing the following code
final dataSnapshot = snapshot.data!.snapshot;
(dataSnapshot.value as Map<String?, dynamic>).forEach((key, value) {
tips.add(value);
});
to
Map<Object?, Object> dataSnapshot = snapshot.data!.snapshot;
Map<String?, dynamic> castedData = dataSnapshot.cast<String?, dynamic>();
castedData.values.forEach((key, value) {
tips.add(value);
});
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