I have a database in my Firebase Realtime database with children that look like this:
以下是我在 Flutter 应用程序中通过 firebase 调用收到的 JSON:
{
"gameAnalytics" : {
"log" : {
"20210926073039AbMc4uSXywqpK9OcusSV" : {
"cityID" : "newYork",
"countryCode" : "USA",
"gameID" : "20210927065000Upper90IndnewYofootbiGZYy",
"gamePaymentMethod" : "payAtPitch",
"players" : {
"umZ5ezrtI6a3UoCDWFDc3hInoNA2" : {
"pnam" : "Mario Rest",
"url" : "https://i.ibb.co/blahblah.jpg"
}
},
"sportID" : "football",
"status" : {
"202109261130395laHd8h77R" : "completing, send back",
"20210926113039BcUQ8RdbHs" : "payAtPitch",
"20210926113039Ck9JsD1uf1" : "playersAdded"
},
"timeAndDateString" : "20210926073039",
"totalCost" : 999,
"type" : "ADD",
"userWhoAddedID" : "umZ5ezrtI6a3UoCDWFDc3hInoNA2",
"wantsToBeOrganizer" : true
},
"202109261146540focIuCQRi3wNfSluvkl" : {
"cityID" : "newYork",
"countryCode" : "USA",
"gameID" : "20210927065000Upper90IndnewYofootbiGZYy",
"gamePaymentMethod" : "payByBalance",
"players" : {
"hOBQJtqCCNgGBVrAv2MqeaFJmdu1" : {
"pnam" : "Seong Kang",
"url" : "messi"
}
},
"promoCodeData" : "U90qaL",
"sportID" : "football",
"status" : {
"2021092615465414NXsxwW51" : "playersAdded",
"20210926154654A60TLCmS2t" : "paidByBalance",
"20210926154654VtYR1t4bMZ" : "completing, send back"
},
"timeAndDateString" : "20210926114654",
"totalCost" : 0,
"type" : "ADD",
"userWhoAddedID" : "hOBQJtqCCNgGBVrAv2MqeaFJmdu1",
"wantsToBeOrganizer" : false
},
"20210926204533DjF3lMCMDpvwHfsh6lQJ" : {
"amountToRefund" : 0,
"promoCodes" : {
"hOBQJtqCCNgGBVrAv2MqeaFJmdu1" : "U90qaL"
},
"status" : {
"20210927004533ZWGNEMX27V" : "REFUNDING: 0 null hOBQJtqCCNgGBVrAv2MqeaFJmdu1"
},
"type" : "CANCEL",
"userWhoAddedID" : "hOBQJtqCCNgGBVrAv2MqeaFJmdu1"
}
},
"pitchCost" : 3500,
"playerNumbers" : {
"hoursBefore12" : 2,
"hoursBefore24" : 1,
"hoursBefore3" : 2,
"hoursBefore36" : 1,
"hoursBefore48" : 1,
"hoursBefore6" : 2,
"hoursBefore72" : 1,
"hoursBefore96" : 1
},
"timings" : {
"added" : {
"20210917004938" : "organiserID12345",
"20210926113040" : "umZ5ezrtI6a3UoCDWFDc3hInoNA2",
"20210926154656" : "hOBQJtqCCNgGBVrAv2MqeaFJmdu1"
},
"cancelled" : {
"20210917004939" : "playersUnCancelled",
"20210927004522" : "playersCancelled"
},
"removed" : {
"20210926113042" : "organiserID12345"
}
}
},
"gameData" : {
"addFakePlayers" : false,
"can" : true,
"canAddPromoCode" : true,
"canDes" : {
"en" : "somedesc"
},
"canMes" : "blahblah.",
"cost" : 999,
"cur" : 2,
"currency" : "usd",
"dat" : "20210927065000",
"descriptions" : {
"en" : "blahblah"
},
"dur" : "60 minutes",
"expOrg" : "",
"gameTypes" : {
"en" : "blahblah"
},
"hostConfirmed" : false,
"hostInfo" : {
"hostDescription" : "blahblah",
"hostNickname" : "Mario R",
"hostPhoto" : "https://i.ibb.co/blahblah.jpg",
"isSuperHost" : false
},
"lid" : "Upper90IndoorQueensabcde739219515176663407563157034467ap0mr",
"max" : 15,
"mes" : "blahblah",
"mes1" : "my disappointment",
"mes2" : "is immessurable",
"mes3" : "and my day",
"payAtPitchMessage" : {
"en" : "is ruined"
},
"paymentType" : "justOnline",
"paymentsAllowed" : [ "card" ],
"pla1" : {
"hOBQJtqCCNgGBVrAv2MqeaFJmdu1" : {
"pnam" : "blahblah",
"url" : "messi"
}
},
"pla2" : {
"umZ5ezrtI6a3UoCDWFDc3hInoNA2" : {
"organizer" : true,
"pnam" : "Mario Rest",
"url" : "https://i.ibb.co/blahblah.jpg"
}
},
"pub" : false,
"removalAllowed" : true,
"showHostConfirmButton" : false,
"spotEn" : true,
"surl" : "https://someurl",
"title" : {
"en" : "ok"
}
},
"mess" : {
"-MjlDj5szZxKaDs0p3CN" : {
"mes" : "ok",
"tim" : "20210916204938",
"unm" : "blahblah",
"usi" : "XwyPhbjzeKNYVczPdCPFTG0DZbj1"
},
"-MjlDj6bnMvKUO76EjLE" : {
"mes" : "ok",
"tim" : "20210916204938",
"unm" : "blahblah",
"usi" : "XwyPhbjzeKNYVczPdCPFTG0DZbj1"
},
"-MjlDj7SeqRV0KzRzFFX" : {
"mes" : "ok",
"tim" : "20210916204939",
"unm" : "bllblb",
"usi" : "XwyPhbjzeKNYVczPdCPFTG0DZbj1"
},
"-MjlDj8C-p406IK8I-cb" : {
"mes" : "msg",
"tim" : "20210916204940",
"unm" : "msg",
"usi" : "XwyPhbjzeKNYVczPdCPFTG0DZbj1"
}
},
"payment" : {
"playerPaymentStatus" : {
"hOBQJtqCCNgGBVrAv2MqeaFJmdu1" : {
"date" : "20210927004533",
"refundedAmount" : 0,
"stripePaymentNotConfirmed" : true,
"type" : "notPaidForGame",
"userWhoAddedID" : "hOBQJtqCCNgGBVrAv2MqeaFJmdu1"
}
}
},
"userReview" : {
"showReview" : true
}
}
我正在尝试创建一个Map<String, dynamic>
通过使用 Map.from() 来获取此响应,如下所示:
class PickUpGameItem extends StatefulWidget {
final String gameId;
const PickUpGameItem(this.gameId, [Key? key]) : super(key: key);
@override
_PickUpGameItemState createState() => _PickUpGameItemState();
}
class _PickUpGameItemState extends State<PickUpGameItem> {
late StreamSubscription _pickUpGameDetailsStreamSub;
PickUpGameDetails? gameDetails;
@override
void initState() {
super.initState();
_setListeners();
}
@override
void deactivate() {
_pickUpGameDetailsStreamSub.cancel();
super.deactivate();
}
void _setListeners() {
_pickUpGameDetailsStreamSub = FirebaseDatabase()
.reference()
.child(
'.../gamesDetailed/${widget.gameId}/')
.onValue
.listen((event) {
final detailsJson = Map<String, dynamic>.from(event.snapshot.value);
setState(() {
gameDetails = PickUpGameDetails.fromJson(detailsJson);
print(gameDetails.toString());
});
});
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: const Image(
fit: BoxFit.fill,
width: 80.0,
height: 80.0,
image: AssetImage('assets/images/temp_city_img.jpg'),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
'Lorem ipsum dolor sit amet this is a test ......................................',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
SizedBox(
height: 10,
),
Text(
'Lorem ipsum dolor sit amet this is a test ......................................',
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.normal,
fontSize: 14),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
const SizedBox(
width: 10,
),
Flexible(
flex: 0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Football',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
),
const SizedBox(
height: 10,
),
Row(
children: const [
Text(
'14/16',
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.normal,
fontSize: 14),
),
SizedBox(
width: 5,
),
Icon(Icons.ac_unit)
],
),
],
),
),
],
),
);
}
}
当我运行该应用程序时,收到一条错误消息,指出内部链接哈希映射不是映射的子类型,并且在调用 GameAnalytics.fromJson() 时发生错误。我看过多个类似的帖子,但他们的错误提到了 _InternalLinkedHashMap 映射。为什么我的回复中使用这个链接的哈希图Object?
对于键和值?
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type '_InternalLinkedHashMap<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>'
这是我的 dart 模型类:
PickUpGameDetails.dart:
class PickUpGameDetails {
GameAnalytics? gameAnalytics;
GameData? gameData;
UserReview? userReview;
PickUpGameDetails(
{required this.gameAnalytics,
required this.gameData,
required this.userReview});
PickUpGameDetails.fromJson(Map<String, dynamic> json) {
gameAnalytics = json['gameAnalytics'] != null
? GameAnalytics.fromJson(json['gameAnalytics'])
: null;
gameData =
json['gameData'] != null ? GameData.fromJson(json['gameData']) : null;
userReview = json['userReview'] != null
? UserReview.fromJson(json['userReview'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (gameAnalytics != null) {
data['gameAnalytics'] = gameAnalytics!.toJson();
}
if (gameData != null) {
data['gameData'] = gameData!.toJson();
}
if (userReview != null) {
data['userReview'] = userReview!.toJson();
}
return data;
}
}
游戏分析.dart:
class GameAnalytics {
late int pitchCost;
PlayerNumbers? playerNumbers;
Timings? timings;
GameAnalytics(
{required this.pitchCost,
required this.playerNumbers,
required this.timings});
GameAnalytics.fromJson(Map<String, dynamic> json) {
pitchCost = json['pitchCost'];
playerNumbers = json['playerNumbers'] != null
? PlayerNumbers.fromJson(json['playerNumbers'])
: null;
timings =
json['timings'] != null ? Timings.fromJson(json['timings']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['pitchCost'] = pitchCost;
if (playerNumbers != null) {
data['playerNumbers'] = playerNumbers!.toJson();
}
if (timings != null) {
data['timings'] = timings!.toJson();
}
return data;
}
}
PlayerNumbers.dart:
class PlayerNumbers {
late int hoursBefore12;
late int hoursBefore24;
late int hoursBefore3;
late int hoursBefore36;
late int hoursBefore48;
late int hoursBefore6;
late int hoursBefore72;
late int hoursBefore96;
PlayerNumbers(
{required this.hoursBefore12,
required this.hoursBefore24,
required this.hoursBefore3,
required this.hoursBefore36,
required this.hoursBefore48,
required this.hoursBefore6,
required this.hoursBefore72,
required this.hoursBefore96});
PlayerNumbers.fromJson(Map<String, dynamic> json) {
hoursBefore12 = json['hoursBefore12'];
hoursBefore24 = json['hoursBefore24'];
hoursBefore3 = json['hoursBefore3'];
hoursBefore36 = json['hoursBefore36'];
hoursBefore48 = json['hoursBefore48'];
hoursBefore6 = json['hoursBefore6'];
hoursBefore72 = json['hoursBefore72'];
hoursBefore96 = json['hoursBefore96'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['hoursBefore12'] = hoursBefore12;
data['hoursBefore24'] = hoursBefore24;
data['hoursBefore3'] = hoursBefore3;
data['hoursBefore36'] = hoursBefore36;
data['hoursBefore48'] = hoursBefore48;
data['hoursBefore6'] = hoursBefore6;
data['hoursBefore72'] = hoursBefore72;
data['hoursBefore96'] = hoursBefore96;
return data;
}
}
计时.dart:
class Timings {
Map<String, dynamic>? added;
Map<String, dynamic>? cancelled;
Map<String, dynamic>? removed;
Timings(
{required this.added, required this.cancelled, required this.removed});
Timings.fromJson(Map<String, dynamic> json) {
added = json['added'];
cancelled = json['cancelled'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (added != null) {
data['added'] = added;
}
if (cancelled != null) {
data['cancelled'] = cancelled;
}
if (removed != null) {
data['removed'] = removed;
}
return data;
}
}
用户评论.dart:
class UserReview {
bool? showReview;
UserReview({required this.showReview});
UserReview.fromJson(Map<String, dynamic> json) {
showReview = json['showReview'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['showReview'] = showReview;
return data;
}
}
游戏数据.dart:
class GameData {
late bool addFakePlayers;
late bool hasBeenCancelled;
late bool canAddPromoCode;
late String cancellationDescription;
late String cancellationMsg;
late int cost;
late int cur;
late String currency;
late String dateTime;
late String description;
late String durationMsg;
late String expOrg;
late String gameTypeMsg;
late bool hostConfirmed;
late String lid;
late int maxPlayers;
late List<String> messages;
late String payAtPitchMessage;
late String paymentType;
late List<String> paymentsAllowed;
Team? team1;
Team? team2;
late bool pub;
late bool removalAllowed;
late bool showHostConfirmButton;
late bool spotEn;
late String surl;
late String title;
GameData(
{required this.addFakePlayers,
required this.hasBeenCancelled,
required this.canAddPromoCode,
required this.cancellationDescription,
required this.cancellationMsg,
required this.cost,
required this.cur,
required this.currency,
required this.dateTime,
required this.description,
required this.durationMsg,
required this.expOrg,
required this.gameTypeMsg,
required this.hostConfirmed,
required this.lid,
required this.maxPlayers,
required this.messages,
required this.payAtPitchMessage,
required this.paymentType,
required this.paymentsAllowed,
required this.team1,
required this.team2,
required this.pub,
required this.removalAllowed,
required this.showHostConfirmButton,
required this.spotEn,
required this.surl,
required this.title});
GameData.fromJson(Map<String, dynamic> json) {
addFakePlayers = json['addFakePlayers'];
hasBeenCancelled = json['can'];
canAddPromoCode = json['canAddPromoCode'];
cancellationDescription = json['canDes']['en'];
cancellationMsg = json['canMes'];
cost = json['cost'];
cur = json['cur'];
currency = json['currency'];
dateTime = json['dat'];
description = json['descriptions']['en'];
durationMsg = json['dur'];
expOrg = json['expOrg'];
gameTypeMsg = json['gameTypes']['en'];
hostConfirmed = json['hostConfirmed'];
lid = json['lid'];
maxPlayers = json['max'];
messages.add(json['mes']);
messages.add(json['mes1']);
messages.add(json['mes2']);
messages.add(json['mes3']);
payAtPitchMessage = json['payAtPitchMessage']['en'];
paymentType = json['paymentType'];
paymentsAllowed = json['paymentsAllowed'].cast<String>();
team1 = json['pla1'] != null ? Team.fromJson(json['pla1']) : null;
team2 = json['pla2'] != null ? Team.fromJson(json['pla2']) : null;
pub = json['pub'];
removalAllowed = json['removalAllowed'];
showHostConfirmButton = json['showHostConfirmButton'];
spotEn = json['spotEn'];
surl = json['surl'];
title = json['title']['en'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['addFakePlayers'] = addFakePlayers;
data['can'] = hasBeenCancelled;
data['canAddPromoCode'] = canAddPromoCode;
data['canDes'] = cancellationDescription;
data['canMes'] = cancellationMsg;
data['cost'] = cost;
data['cur'] = cur;
data['currency'] = currency;
data['dat'] = dateTime;
data['descriptions'] = description;
data['dur'] = durationMsg;
data['expOrg'] = expOrg;
data['gameTypes'] = gameTypeMsg;
data['hostConfirmed'] = hostConfirmed;
data['lid'] = lid;
data['max'] = maxPlayers;
data['mes'] = messages.elementAt(0);
data['mes1'] = messages.elementAt(1);
data['mes2'] = messages.elementAt(2);
data['mes3'] = messages.elementAt(3);
data['payAtPitchMessage'] = payAtPitchMessage;
data['paymentType'] = paymentType;
data['paymentsAllowed'] = paymentsAllowed;
data['pla1'] = team1?.toJson();
data['pla2'] = team2?.toJson();
data['pub'] = pub;
data['removalAllowed'] = removalAllowed;
data['showHostConfirmButton'] = showHostConfirmButton;
data['spotEn'] = spotEn;
data['surl'] = surl;
data['title'] = title;
return data;
}
}
团队.dart:
class Team {
Map<String, Player> players;
Team({required this.players});
factory Team.fromJson(Map<String, dynamic> json) {
Map<String, Player> _players = {};
for (String key in json.keys) {
_players[key] = Player.fromJson(json[key]);
}
return Team(players: _players);
}
Map<String, dynamic> toJson() {
Map<String, dynamic> json = <String, dynamic>{};
for (String key in players.keys) {
json[key] = players[key];
}
return json;
}
}
玩家.dart:
class Player {
String name;
String url;
Player({required this.name, required this.url});
factory Player.fromJson(Map<String, dynamic> json) {
return Player(name: json['pname'], url: json['url']);
}
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json['pname'] = name;
json['url'] = url;
return json;
}
}