将Firestore DocumentSnapshot转换为Flutter中的地图 [英] Convert Firestore DocumentSnapshot to Map in Flutter

查看:56
本文介绍了将Firestore DocumentSnapshot转换为Flutter中的地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Flutter在Firestore中使用嵌套数组更新文档.

I need to update a document with nested arrays in Firestore with Flutter.

因此,我需要将整个文档放入地图中,在"sections"数组中对地图进行重新排序,然后将数据存储回文档中.

So I need to get the full document into a Map, reorder the maps in the "sections" array, and then store the data back into the document.

但是我不熟悉如何将快照(DocumentSnapshot)的数据获取到Map中.

I'm however unfamiliar how I can get the data of the snapshot (DocumentSnapshot) into a Map.

下面的示例对我尝试实现的目标无效:

Below an example that doesn't work of what I try to achieve:

final Map<String, dynamic> doc = snapshot.data as Map<String, dynamic>;

"snapshot.data"包含文档的值.该文档的结构如下所示:

"snapshot.data" contains the values of the document. The structure of the document looks like this:

{
  name: "Course 1"
  sections: [
    {name: "Section 1"},
    {name: "Section 2"}
  ]
}

sections数组中的Maps重新排序后,我需要将数据保存回文档中.

Once the Maps in the sections array have been re-ordered, I need to save the data back into the document.

  • 问题1:如何将snapshot.data的内容读取到Map中?
  • 问题2:是否要删除文档,然后重新添加?还是可以只更新所有内容?

这里是完整功能.相关代码在"onDragFinish"中.

Here the full function. Relevant code is in "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复制到另一个变量时出错:

Error when trying to copy snapshot.data into another variable:

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)

工作示例

感谢您的协助.这是一个对我有用的完整示例:

Thanks all for your assistance. Here a full example that worked for me:

  // 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

As per our discussion snapshot is not a DocumentSnapshot it is AsyncSnapshot

要获取DocumentSnaphot,请使用snapshot.data

to get the DocumentSnaphot use snapshot.data

要获取实际地图,可以使用snapshot.data.data

to get the actual map you can use snapshot.data.data

这篇关于将Firestore DocumentSnapshot转换为Flutter中的地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆