在 Flutter 中将 Firestore DocumentSnapshot 转换为 Map [英] Convert Firestore DocumentSnapshot to Map in Flutter

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

问题描述

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

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

所以我需要将整个文档放入一个 Map 中,重新排列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) 的数据放入地图中.

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"}
  ]
}

在对部分数组中的地图重新排序后,我需要将数据保存回文档中.

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()

这将返回 Map您正在寻找.

Which will return the Map<String, dynamic> you are looking for.

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

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