gpt4 book ai didi

java - _InternalLinkedHashMap 不是类型转换中自定义类的子类型。从 Firestore 检索 map 数组

转载 作者:行者123 更新时间:2023-12-02 08:58:05 25 4
gpt4 key购买 nike

我将来自自定义类“PollOption”的数据存储在 firestore 中作为 map 数组。当我尝试检索数据时,出现此错误

_InternalLinkedHashMap<String, dynamic> is not a subtype of 'PollOption' in type cast.

我的其他数据检索正常。

我的模型正在存储到集合中。 PollOption 嵌套在此:

class Question{
//single values
final Timestamp askedOn;
final String chosenAnswer;
final String askedBy;
...

//arrays
final List<String> categories;
final List<String> declinedUsers;
final List<PollOption> pollOptions;
...


Question({
this.askedBy,
this.askedByAvatar,
this.askedByName,

...

this.pollOptions,
this.starredMessages,

...

});

我的 PollOption 模型:

class PollOption{
final String option;
final bool selected;
final int optionNumber;
final int votes;

PollOption({this.option, this.optionNumber, this.selected, this.votes});
}

我如何将数据存储到 Firestore:

Future createQuestion(Question data) async {
...

List<Map> sterilizedPolls (){
List<Map> polls = [];
if(data.pollOptions != null){
data.pollOptions.forEach((PollOption pollOption){
Map option ={
'option': pollOption.option,
'votes': pollOption.votes,
'optionNumber': pollOption.optionNumber,
'selected': pollOption.selected,
};
polls.add(option);
});

}
return polls;

}


return await questionCollection.add({
'askedBy': uid,
...
'declinedUsers': [],
'pollOptions': sterilizedPolls(),

...


});

}

我如何检索数据:

//Getting all the questions I want
Future<List<Question>> getOpenQuestions() async{
final QuerySnapshot result = await questionCollection
.where('locked', isEqualTo: false)
.where('chosenAnswer', isEqualTo: '')
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
final List<Question> openQuestions = [];
documents.forEach((data){
print('accessing database');
openQuestions.add(
Question(
question: data['question'],

)
);
});

return openQuestions;
}

//Creating list from snapshot
List<Question> _questionListFromSnapshot(QuerySnapshot snapshot) {



return snapshot.documents.map((doc){

return Question(
askedBy: doc.data['askedBy'] ?? '',
askedByName: doc.data['askedByName'] ?? 'Anonymous',

...

pollOptions: List.from(doc.data['pollOptions']).cast<PollOption>() ?? [],

...

);
}).toList();





}

//creating stream
Stream<List<Question>> get openQuestionList {
try {
return questionCollection
.where('locked', isEqualTo: false)
.snapshots()
.map(_questionListFromSnapshot);

} catch (e) {
return e;
}

}

以及我如何显示数据:

class OpenQuestions extends StatelessWidget {
@override
Widget build(BuildContext context) {

final openQuestions = Provider.of<List<Question>>(context) ?? [];

return StreamBuilder<List<Question>>(
stream: QuestionDatabaseService().openQuestionList,
builder: (context, snapshot){
if(snapshot.hasError){
return Text('Error!');
}
if (snapshot.hasData){
return ListView.builder(
itemCount: openQuestions.length,
itemBuilder: (context, index) {
return QuestionTile(question: openQuestions[index], context: context);
},
);
}else{
return Loading();
}

}

);

//The QuestionTile Loaded

class QuestionTile extends StatelessWidget {

final Question question;
final context;

QuestionTile({this.question, this.context});

@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Card(
child: ListTile(
...
title: Text(question.question),
subtitle: question.poll == false ? Text(question.message) : Text('Poll'),
onTap: (){
_showBottomModal(context, question);
},
),
),

);
}
}

//The bottom modal that pops up
void _showBottomModal(context, question)async {
showModalBottomSheet(context: context, isScrollControlled: true, builder: (context){
return Container(
//color: Color(0xFF737373),
child: Container(
child: FractionallySizedBox(

//Where the problem widget is being called

child: AnswerQuestion(question: question),
heightFactor: 0.90,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(30.0),
topRight: const Radius.circular(30.0),
)
),

),
);
});
}

//AnswerQuestion widget where the error is occurring

class _AnswerQuestionState extends State<AnswerQuestion> {

...



@override
Widget build(BuildContext context) {



return Container(

child:Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
...
Form(
key: _formKey,
child: Column(
children: [
//Where the data is being displayed with error

ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 300.0
),
child: Container(
child: ListView.builder(
itemCount: widget.question.pollOptions.length,
itemBuilder: (BuildContext context, int index){



return ListTile(
title: Text(widget.question.pollOptions[index].option),
leading: Radio(
value: widget.question.pollOptions[index].optionNumber,
groupValue: _optionSelected,
onChanged: _handleRadioValueChange,
),
);

...

抱歉,如果代码太多(或不够),我仍在学习 Flutter,并希望提供尽可能多的内容来帮助解决此错误。

最佳答案

问题在于行:

pollOptions: List.from(doc.data['pollOptions']).cast<PollOption>() ?? [],

doc.data['pollOptions'] 中的值实际上是 JSON 数据,在 dart 中表示为 Map<String, dynamic> 。 Dart 不知道如何自动将 Map 转换为您的对象 PollOption

考虑这个:

pollOptions: doc.data['pollOptions'].map((Map<String, dynamic> json) => PollOption.fromJson(json)).toList()

假设 doc.data['pollOptions']返回一个列表,如果它是 JSON 数组,则应该这样做。

当然你需要一个fromJson您的工厂构造函数 PollOption类:

class PollOption {
...
factory PollOption.fromJson(final Map<String, dynamic> json) {
return PollOption(json["optionkey"], etc);
}
...
}

关于java - _InternalLinkedHashMap<String,dynamic> 不是类型转换中自定义类的子类型。从 Firestore 检索 map 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60367869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com