I want to display a chessboard with data synchronized with Firestore in real time. After creating a room document on Firestore, I pulled data from that document to the app and used StreamBuilder to display it. But a very confusing error appears:
The following _TypeError was thrown building StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(dirty, state: _StreamBuilderBaseState<DocumentSnapshot<Map<String, dynamic>>, AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>>>#954da):
type 'List' is not a subtype of type 'List<Map<String, dynamic>>' in type cast
Here’s the code:
Stream<DocumentSnapshot<Map<String, dynamic>>> watchRoom(String roomId) {
return FirebaseFirestore.instance.collection("rooms").doc(roomId).snapshots();
}
class OnlineBoardWidget extends StatelessWidget {
const OnlineBoardWidget({super.key});
@override
Widget build(BuildContext context) {
final columnCount = OnlineGameController.to.room.board.columnCount;
final rowCount = OnlineGameController.to.room.board.rowCount;
logger.t('build online board ($rowCount, $columnCount)');
return StreamBuilder(
// theo dõi một room document trên firestore
stream: firestoreService.watchRoom("ec483c14-f414-44ae-bea1-b84e409331f0"),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
Map<String, dynamic> json = snapshot.data!.data()!;
logger.i(json); // json data is logged
OnlineRoom room = OnlineRoom.fromJson(json); // ERROR apears here
logger.i(room);
return Text(room.toString(), style: kNormalText,);
}
},
);
}
}
Noticed a problem with the OnlineRoom.fromJson() method. I wrote a short piece of code to check in the main() function. But I see that the OnlineRoom.fromJson() method works properly. Why is there a difference between the fromJson() function when pulling data from Firebase and the available data?
final object = OnlineRoom.fromJson(roomJsonSnippet);
logger.i(object); // no error, the object is logged correctly
Map<String, dynamic> roomJsonSnippet = {
"winCount": 5,
"historyBoard": {
"cells": {
"0": [
{
"column": 0,
"row": 0,
"state": "normal",
"content": "noSeed"
},
{
"column": 1,
"row": 0,
"state": "normal",
"content": "noSeed"
}
],
"1": [
{
"column": 0,
"state": "normal",
"row": 1,
"content": "noSeed"
},
{
"column": 1,
"row": 1,
"state": "normal",
"content": "noSeed"
}
]
},
"rowCount": 2,
"columnCount": 2
},
"name": "Untitled Room",
"historyRoundIndex": 0,
"id": "ec483c14-f414-44ae-bea1-b84e409331f0",
"state": "playing",
"rounds": [
{
"historyTurns": [],
"currentPlayerIndex": 0,
"_historyPlayerIndex": 0,
"players": [
{
"score": 0,
"finalScore": null,
"seed": "cross",
"name": "Player 1",
"initialScore": 0,
"index": 0
},
{
"score": 0,
"finalScore": null,
"seed": "nought",
"initialScore": 0,
"name": "Player 2",
"index": 1
}
],
"historyTurnIndex": 0,
"winTurnIndex": null,
"index": 0,
"currentTurnIndex": 0,
"winnerIndex": null,
"turns": []
}
],
"board": {
"cells": {
"0": [
{
"column": 0,
"state": "normal",
"row": 0,
"content": "noSeed"
},
{
"column": 1,
"row": 0,
"state": "normal",
"content": "noSeed"
}
],
"1": [
{
"column": 0,
"state": "normal",
"row": 1,
"content": "noSeed"
},
{
"column": 1,
"row": 1,
"state": "normal",
"content": "noSeed"
}
]
},
"rowCount": 2,
"columnCount": 2
},
"currentRoundIndex": 0
}
Since the type is not indicated from firestore data, I suppose you should cast type like