【问题标题】:Delete map in a firestore table删除 Firestore 表中的地图
【发布时间】:2021-06-02 08:53:46
【问题描述】:

我在删除 Firestore 数据表中的地图时遇到问题。事实上,要么我删除我的整个数组,要么我收到以下类型的错误:

flutter:删除失败 1:无效参数:'_CompactLinkedHashSet'的实例

我将我的课程附加给你,以便你能更好地理解。提前谢谢你

类删除描述:

import 'package:cloud_firestore/cloud_firestore.dart';

class DeleteDescription {
  final String city;
  final String citee;
  final int value;
  CollectionReference cities = FirebaseFirestore.instance.collection('city');

  DeleteDescription(this.city, this.citee, this.value) {
    deleteDescription();
  }

  Future<void> deleteDescription() {
    return cities
        .doc(city)
        .collection("citee")
        .doc(citee)
        .set({
          "Description": FieldValue.arrayRemove([
            {0}
          ])
        })
        .then((value) => print("$citee Deleted"))
        .catchError((error) => print("Failed to delete $value: $error"));
  }
}

类读描述:

import 'package:ampc_93/fonction/firebase_crud/delete_description.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class ReadDescription extends StatefulWidget {
  final String titreCity;
  final String titreCitee;

  ReadDescription(this.titreCity, this.titreCitee);

  @override
  _ReadDescriptionState createState() => _ReadDescriptionState();
}

class _ReadDescriptionState extends State<ReadDescription> {
  @override
  Widget build(BuildContext context) {
    CollectionReference cities = FirebaseFirestore.instance.collection("city");
    return FutureBuilder<DocumentSnapshot>(
      future: cities
          .doc(widget.titreCity)
          .collection("citee")
          .doc(widget.titreCitee)
          .get(),
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Text("Something went wrong");
        }
        if (snapshot.hasData && !snapshot.data!.exists) {
          return Text("Documents does not exist");
        }
        if (snapshot.connectionState == ConnectionState.done) {
          var data = snapshot.data!.data() as Map<String, dynamic>;
          if (data["Description"] == null) {
            return Text("");
          } else {
            return ListView.separated(
                itemBuilder: (context, index) {
                  return ListTile(
                      title: Text(
                        data["Description"][index]["Identite"],
                        textAlign: TextAlign.justify,
                      ),
                      subtitle: Text(
                        data["Description"][index]["Role"],
                        textAlign: TextAlign.justify,
                        style: TextStyle(
                            decoration: TextDecoration.underline,
                            color: Colors.red),
                      ),
                      leading: Icon(Icons.person),
                      trailing: IconButton(
                        onPressed: () => DeleteDescription(
                            widget.titreCity, widget.titreCitee, index),
                        icon: Icon(Icons.delete_forever),
                        color: Colors.red[300],
                      ));
                },
                separatorBuilder: (context, index) => Divider(),
                itemCount: data["Description"].length);
          }
        }
        return Text("Loading");
      },
    );
  }
}

我指定在我的数据库中,“描述”是一个数组,因此我想删除“描述”编号为 0 的所有元素,例如

【问题讨论】:

    标签: flutter google-cloud-firestore


    【解决方案1】:

    您使用的FieldValue.arrayRemove 没有以这种方式工作。有两种方法可以从 Firestore 列表中删除数据。 第一种方法是在FieldValue.arrayRemove 中传递要删除的元素(不是索引)。 第二种方法是从firestore获取集合并根据您的需要修改数据并更新firestore中的集合。 查看下面的代码以获得更多理解。

    import 'package:cloud_firestore/cloud_firestore.dart';
    
    class DeleteDescription {
      final String city;
      final String citee;
      final int value;
      CollectionReference cities = FirebaseFirestore.instance.collection('city');
    
      DeleteDescription(this.city, this.citee, this.value) {
        deleteDescription();
      }
    
      Future<void> deleteDescription() {
       final snapshot = await cities.doc(city).collection("citee").doc(citee).get();
      
      /* Get list from firestore */
      final list = snapshot["Description"] as List;
     
      /* Remove first or any element and delete from list */
      list.removeAt(0);
      
      /* Update same list in firestore*/
      await cities
        .doc(city)
        .collection("citee")
        .doc(citee)
          .set({"Description": list}).then((value) => print(" Deleted"));
    
       
      }
    }
    

    【讨论】:

    • @L'Alphamerc 另一方面,因为它是一个异步函数,我不能再用“Setstate”更新我的列表,我必须返回并返回我的页面要更新的 ListView。有人有想法吗?
    • @pierrot0630 您可以将节点侦听器添加到任何特定集合。每当它更改或添加文档时,侦听器都会监听这些更改,您可以更新您的 UI。
    • 看看这个答案 -> stackoverflow.com/a/61184021/9390431
    • 考虑 Firestore“数组”的一个有用方法是它们绝对不是数组 - 它们是有序列表,显示的“数字”是顺序,而不是索引。 “识别” Firestore Array[ordered list] 中单个元素的唯一方法是通过它的准确和完整值。
    【解决方案2】:

    考虑 Firestore“数组”的一种有用方法是它们绝对不是数组 - 它们是有序列表(按它们添加到数组的顺序或者 , 它们在作为数组传递给 API 的数组中的顺序),显示的“数字”是顺序,而不是索引。在 Firestore Array[有序列表] 中“识别”单个元素的唯一方法是通过它的准确和完整值。很不幸他们选择了“数组”这个名字。

    也就是说,当您阅读文档时,呈现给 CODE 的结果以数组的形式呈现,并且获得了通过索引引用元素的能力 - 这就是您必须这样做的原因:

    => 在后端/API 调用中,通过“值”指定一个元素,在这种情况下是列表中的 ENTIRE 对象

    => 在客户端,读取文档,通过索引或值删除所需元素,然后将整个数组写回后端。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 2021-05-03
      • 2018-05-08
      相关资源
      最近更新 更多