我有一个带有questions
集合的Cloud Firebase数据库。每个question
都有一个地图options
的列表。
我正在使用Flutter,并且有question
和option
的以下类:
class Question {
final String text;
final List<Option> options; // I have tried changing this to List<dynamic> but it doesn't help
final String reference;
Question(this.text, this.options, this.reference);
Question.fromMap(Map<String, dynamic> map, {this.reference}) :
text = map['text'],
options = map['options']; // here the error happens
Question.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.documentID);
}
和option
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<String, dynamic> map) :
text = map['text'],
votes = map['votes'];
}
我真的不知道该如何解决。但是,这种错误似乎在互联网上无处不在。任何帮助表示赞赏。
更新
供您参考:options
是Cloud Firestore中的一组地图。
我根据以下两个答案将代码更改为:
factory Question.fromMap(Map<String, dynamic> map) {
var options = map['options'];
var text = map['text'];
var reference = map['documentID'];
List<Option> optionsList = options.cast<Option>();
return new Question(
text = text,
options = optionsList,
reference = reference
);
}
factory Question.fromSnapshot(DocumentSnapshot snapshot) {
return Question.fromMap(snapshot.data);
}
仍然出现此错误:type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Option' in type cast
我已经看到并尝试了许多答案,而且所有人似乎都说相同的话。我只是想不通。
Cloud Firestore的屏幕截图:
答案 0 :(得分:1)
我以前遇到过这个问题,我用
解决了这是我的代码,您可以将其转换为您的代码:
UserModel.fromSnapshot(DocumentSnapshot snapshot)
: documentReference = snapshot.reference,
username = snapshot['username'],
firstName = snapshot['firstName'],
lastName = snapshot['lastName'],
picture = snapshot['picture'],
routes = Map.from(snapshot['routes']),
avgScore = snapshot['avgScore'];
}
您在cloud_firestore上的字段类型是什么?
如果它是Map
尝试使用Map.from()
如果是List
,请尝试使用List.from()
,然后将您的本地字段更改为相同的类型。
答案 1 :(得分:1)
遇到类似问题后,这对我来说非常合适:
class Question {
final String text;
final List<Option> options = [];
final String reference;
Question(this.text, this.options, this.reference);
Question.fromMap(Map<String, dynamic> map, {this.reference}){
text = map['text'];
if (map['options'] != null) {
map['options'].forEach((v) {
options.add(new Option.fromMap(v));
});
}
}
Question.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.documentID);
}
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<String, dynamic> map) :
text = map['text'],
votes = map['votes'];
}
答案 2 :(得分:0)
要消除此错误,我们必须显式转换动态值。 代替
Question.fromMap(Map<String, dynamic> map, {this.reference}) :
text = map['text'],
options = map['options'];
使用
factory Question.fromMap(Map<String, dynamic> map, {this.reference}) {
var optionsFromMap = map['options'];
//you can use both the steps to check which one will work perfectly for you
// List<Option> optionsList = new List<Option>.from(optionsFromMap)
List<Option> optionsList = optionsFromMap.cast<Option>();
return new Question(
text = map['text'],
options = map['options'];
);
}
当我想要列表值时,上面的代码可以正常工作
我希望这会对您有所帮助。
答案 3 :(得分:0)
我最终遵循了@chipli onat
的建议,并将其与@harsh
的答案混合在一起,最终使它起作用。这是我的代码现在的样子:
class Question {
final String text;
final String reference;
final List<Map> options;
Question(this.text, this.options, this.reference);
factory Question.fromMap(Map<String, dynamic> map, String reference) {
var options = map['options'];
var text = map['text'];
List<Map> optionsList = options.cast<Map>();
return new Question(
text = text,
options = optionsList,
reference = reference
);
}
factory Question.fromSnapshot(DocumentSnapshot snapshot) {
return Question.fromMap(snapshot.data, snapshot.documentID);
}
}
和
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<dynamic, dynamic> map) : // notice Map<dynamic, dynamic> here
text = map['text'],
votes = map['votes'];
}
我敢肯定,这个答案可以改善,但是老实说,我不完全理解为什么它必须如此困难。希望这个答案对您有所帮助。
答案 4 :(得分:0)
此代码比建议的解决方案更具可读性。我在项目中使用了它。
var optionsMap = map['options'] as List;
List<Option> optionsList = optionsMap.map((o) => Option.fromMap(o.cast<String, dynamic>())).toList();
class Option {
final String text;
final int votes;
bool isSelected;
Option(this.text, this.votes, this.isSelected);
Option.fromMap(Map<dynamic, dynamic> map) : // notice Map<dynamic, dynamic> here
text = map['text'],
votes = map['votes'];
}