首页 > 解决方案 > List.add 无法正常工作

问题描述

EventDetails 类的代码

class EventDetails {
EventDetails(
      {
      required this.description,
      required this.date,
      required this.startTime,
      required this.endTime,
      required this.speaker,
      required this.isFavorite});

  String description;
  String date;
  String startTime;
  String endTime;
  String speaker;
  String isFavorite;}

网络类代码

class Network {
  static Future<List<EventDetails>> getEvents() async {
    Firebase.initializeApp();
    FirebaseFirestore instance = FirebaseFirestore.instance;
    var data = await instance.collection('event_details').get();
    return makeEvents(data.docs);
  }

  static List<EventDetails> makeEvents(List<dynamic> collection) {
    List<EventDetails> events = [];
    collection.forEach((event) {
      print('++++++++++++++==========');
      print(event['description']);
      print(event['date']);
      print(event['start_time']);
      print(event['end_time']);
      print(event['speaker']);
      print(event['is_favorite']);

  events.add(
    EventDetails(
      description: event['description'],
      date: event['date'],
      startTime: event['start_time'],
      endTime: event['end_time'],
      speaker: event['speaker'],
      isFavorite: event['is_favorite'],
    ),
  );
});
print('--------');
print(events.length);
return events;
  }
}

在上面的代码中,我试图在 getEvents 函数中从 cloud firestore 获取数据,并通过 makeEvents 函数转换为 EventDetails 来返回数据。问题出在我的 makeEvents 函数中,我在整个数据上设置了 forEach,首先我打印整个数据,然后添加到事件详细信息列表中,但在第一次迭代中打印了数据,但之后没有任何反应,并且列表或列表长度没有更新

我的构建方法

@override
  Widget build(BuildContext context) {
    return FutureBuilder<List<EventDetails>>(
      future: Network.getEvents(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(snapshot.data![index].description),
                );
              });
        }
        return const Center(
          child: CircularProgressIndicator(),
        );
      },
    );
  }

我的收藏结构

在此处输入图像描述

标签: listfluttergoogle-cloud-firestoreflutter-futurebuilder

解决方案


首先,Firebase.initializeApp();是一个异步函数。你应该等待它。所以改为await Firebase.initializeApp();

其次,你应该把它await Firebase.initializeApp();放在你的main(),而不是Network课堂上。

尝试这个。

class Network {
  static Future<List<EventDetails>> getEvents() async {
    // await Firebase.initializeApp();
    // move above to main() in main.dart
    FirebaseFirestore instance = FirebaseFirestore.instance;
    QuerySnapshot<EventDetails> query = await instance
        .collection('event_details')
        .withConverter<EventDetails>(
          fromFirestore: (snapshot, _) => EventDetails.fromFirestore(snapshot),
          toFirestore: (data, _) => data.toJson(),
        )
        .get();
    List<EventDetails> events = query.docs.map((e) => e.data()).toList();
    print(events);
    return events;
  }
}

将此添加到您的事件模型中

factory EventDetails.fromFirestore(DocumentSnapshot<Map<String, dynamic>> snapshot) {
  Map<String, dynamic> json = snapshot.data();
  return EventDetails(
    id: snapshot.id,
    // The above gives you the document id in the model
    // you should add id to your model
    description: json['description'] as String,
    date: json['date'] as String,
    // startTime and endTime should be dateTime;
    startTime: json['start_time'],
    endTime: json['end_time'],
    // speaker should be map
    speaker: json['speaker'],
    isFavorite: json['is_favorite'] as bool,
  );
}
Map<String, dynamic> toJson() => <String, dynamic>{
  'description': this.description,
  'date': this.date,
  'start_time': this.startTime,
  'end_time': this.endTime,
  'speaker': this.speaker,
  'is_favorite': this.isFavorite,
};

推荐阅读