我需要使用Flutter在Firestore中使用嵌套数组更新文档。
因此,我需要将整个文档放入地图中,在“ sections”数组中对地图重新排序,然后将数据存储回文档中。
但是,我不熟悉如何将快照(DocumentSnapshot)的数据获取到Map中。
下面的示例对我尝试实现的目标不起作用:
final Map<String, dynamic> doc = snapshot.data as Map<String, dynamic>;
“ snapshot.data”包含文档的值。该文档的结构如下所示:
{ name: "Course 1" sections: [ {name: "Section 1"}, {name: "Section 2"} ] }
对sections数组中的Maps重新排序后,我需要将数据保存回文档中。
这里功能齐全。相关代码在“ onDragFinish”中。
// Build editable list with draggable list tiles and swipe to delete List<Widget> buildListViewEdit() { final course = db.collection("school").document("3kRHuyk20UggHwm4wrUI") .collection("course").document("74UsE9x7Bsgnjz8zKozv").snapshots(); return [ StreamBuilder( stream: course, builder: (context, snapshot) { if (!snapshot.hasData) return const Text("Loading..."); return Expanded( child: DragAndDropList( snapshot.data["sections"].length, itemBuilder: (context, index) { return Card( child: ListTile( title: Text(snapshot.data["sections"][index]["name"]), onTap: () { print("hello"); } ) ); }, onDragFinish: (before, after) { print('on drag finish $before $after'); //final docString = snapshot.data.toString(); final Map <String, dynamic> doc = snapshot.data; //final tempSections = List.castFrom(snapshot.data["sections"]).toList(); //Map data = tempSections[before]; //tempSections.removeAt(before); //tempSections.insert(after,data); //snapshot.data["sections"] = tempSections; //db.collection("school").document("3kRHuyk20UggHwm4wrUI") //.collection("course").document("74UsE9x7Bsgnjz8zKozv").updateData(snapshot.data); //var line = snapshot.data["sections"][before]; //snapshot.data["sections"].removeAt(before); //snapshot.data["sections"].insert(after,line); /* List<Map> sections = docCopy["sections"]; Map data = docCopy["sections"][before]; sections.removeAt(before); sections.insert(after, data); print(sections); */ }, canDrag: (index) { print('can drag $index'); return index != 3; }, canBeDraggedTo: (one, two) => true, dragElevation: 8.0, ) ); } ) ]; }
尝试将snapshot.data复制到另一个变量时出错:
flutter: ══╡ EXCEPTION CAUGHT BY GESTURE LIBRARY ╞═══════════════════════════════════════════════════════════ flutter: The following assertion was thrown while routing a pointer event: flutter: type 'DocumentSnapshot' is not a subtype of type 'Map<String, dynamic>' flutter: flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially flutter: more information in this error message to help you determine and fix the underlying cause. flutter: In either case, please report this assertion by filing a bug on GitHub: flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md flutter: flutter: When the exception was thrown, this was the stack: flutter: #0 _SectionScreenState.buildListViewEdit.<anonymous closure>.<anonymous closure> (package:teach_mob/screens/section_screen.dart:150:45)
工作实例
谢谢大家的协助。这是一个对我有用的完整示例:
// Build editable list with draggable list tiles and swipe to delete List<Widget> buildListViewEdit() { final course = db.collection("school").document("3kRHuyk20UggHwm4wrUI") .collection("course").document("74UsE9x7Bsgnjz8zKozv").snapshots(); return [ StreamBuilder( stream: course, builder: (context, snapshot) { if (!snapshot.hasData) return const Text("Loading..."); return Expanded( child: DragAndDropList( snapshot.data["sections"].length, itemBuilder: (context, index) { return Card( child: ListTile( title: Text(snapshot.data["sections"][index]["name"]), onTap: () { print("hello"); } ) ); }, onDragFinish: (before, after) { print('on drag finish $before $after'); // Convert AsyncSnapshot to DocumentSnapshot and then // create a map that can be changed and updated. final Map <String, dynamic> doc = snapshot.data.data; // Convert fixed length list to dynamic list, because items in // fixed length lists can't be added / removed. final tempSections = List.castFrom(doc["sections"]).toList(); // Get the data of the list item to be dragged // Remove the data from the current position // Add the data to the new position of the list Map data = tempSections[before]; tempSections.removeAt(before); tempSections.insert(after,data); // Overwrite sections with new list array doc["sections"] = tempSections; // Store the data back into the firestore document db.collection("school") .document("3kRHuyk20UggHwm4wrUI") .collection("course") .document("74UsE9x7Bsgnjz8zKozv") .updateData(doc); }, canDrag: (index) { print('can drag $index'); return index != 3; }, canBeDraggedTo: (one, two) => true, dragElevation: 8.0, ) ); } ) ]; }
根据我们讨论的快照是不是DocumentSnapshot很AsyncSnapshot
DocumentSnapshot
AsyncSnapshot
获得DocumentSnaphot的使用 snapshot.data
snapshot.data
获得可以使用的实际地图 snapshot.data.data
snapshot.data.data