在 Flutter 列表视图中删除 Firestore 数据

Posted

技术标签:

【中文标题】在 Flutter 列表视图中删除 Firestore 数据【英文标题】:Deleting Firestore Data in Flutter List View 【发布时间】:2021-05-03 15:54:11 【问题描述】:

我有一个从 Firestore 获取一些数据的常规列表视图,下面是它的代码:

body: StreamBuilder(
      stream: FirebaseFirestore.instance.collection('orders').snapshots(),
      builder: (context, snapshot) 
        if (!snapshot.hasData)
          return Center(
            child:
                CircularProgressIndicator(), 
          );
        return ListView.builder(
       
          itemCount: snapshot.data.docs.length,
          itemBuilder: (context, index) 
            DocumentSnapshot ds = snapshot.data.docs[index];
  
            return Text(ds['name']);

现在,如果我想在其中的某处创建一个删除按钮,我会这样做:

FirebaseFirestore.instance.collection('orders').doc('ID SHOULD BE HERE').delete();

我遇到的问题是如何在此处找到列表磁贴的文档 ID,以便自动将其从数据库中删除?代码中的ID应该在这里应该是一些命令来找到它的ID,如下面的截图所示:

【问题讨论】:

【参考方案1】:

DocumentSnapshot 包含一个名为 id 的属性,它将返回此快照的文档给定 ID。因此,您可以执行以下操作:

itemBuilder: (context, index) 
  DocumentSnapshot ds = snapshot.data.docs[index];
  print(ds.id);
  return Text(ds['name']);

然后根据id删除它,执行以下操作:

FirebaseFirestore.instance.collection('orders').doc(ds.id).delete();

【讨论】:

那我要这样删除吗? FirebaseFirestore.instance.collection('orders').doc('ds['id']').delete(); FirebaseFirestore.instance.collection('orders').doc(ds.id).delete();【参考方案2】:

通过将 doc 中的参考 id 保存在本地模型中,并在所需的操作集上使用参考 id

我已经提供了删除数据的实时示例。

class Employee 
  Employee(this.employeeID, this.employeeName, this.branch, this.designation, this.location,
      this.salary,
      this.reference);

  double employeeID;

  String employeeName;

  String designation;

  String branch;

  String location;

  double salary;

  DocumentReference reference;

  factory Employee.fromSnapshot(DocumentSnapshot snapshot) 
    Employee newEmployee = Employee.fromJson(snapshot.data());
    newEmployee.reference = snapshot.reference;
    return newEmployee;
  

  factory Employee.fromJson(Map<String, dynamic> json) =>
      _employeeFromJson(json);

  Map<String, dynamic> toJson() => _employeeToJson(this);

  @override
  String toString() => 'employeeName $employeeName';


Employee _employeeFromJson(Map<String, dynamic> data) 
  return Employee(
    data['employeeID'],
    data['employeeName'],
    data['branch'],
    data['designation'],
    data['location'],
    data['salary'],
  );


Map<String, dynamic> _employeeToJson(Employee instance) 
  return 
    'employeeID' : instance.employeeID,
    'employeeName': instance.employeeName,
    'branch': instance.branch,
    'designation': instance.designation,
    'location': instance.location,
    'salary': instance.salary,
  ;

存储库

class EmployeeRepository
  List<Employee> employees = [];

  final CollectionReference collection =
      FirebaseFirestore.instance.collection('employees');

  Stream<QuerySnapshot> getStream() 
    return collection.snapshots();
  
  
  Future<DocumentReference> add(Employee employee) 
    var documentReference = collection.add(employee.toJson());
    return documentReference;
  

  update(Employee employee) async 
    collection.doc(employee.reference.id).update(employee.toJson());
  


  delete(Employee employee) async 
    collection.doc(employee.reference.id).delete();
  

  fromSnapShot(DocumentSnapshot snapshot) => Employee.fromSnapshot(snapshot);

  Future<void> buildData(AsyncSnapshot snapshot) async 
    if (snapshot.data.documents.length == 0) 
      employees = [];
    

    employees = await snapshot.data.documents.map<Employee>((doc) 
      return Employee.fromSnapshot(doc);
    ).toList(growable: false);
  

列表视图构建器

@override
Widget build(BuildContext context) 
  return Scaffold(
    appBar: AppBar(
      title: Text('Employees List'),
    ),
    body: Column(children: [
      StreamBuilder<QuerySnapshot>(
          stream: employeeRepository.getStream(),
          builder: (context, snapShot) 
            if (!snapShot.hasData ||
                snapShot.hasError ||
                snapShot.connectionState == ConnectionState.waiting) 
              return Container(
                child: Center(child: CircularProgressIndicator()),
              );
            
            
              employeeRepository.buildData(snapShot);
              return ListView.builder(
                itemBuilder: (context, index) 
                  final employee = employeeRepository.employees[index];
                  return ListTile(
                    title: Text(employee.employeeName),
                    onLongPress: () 
                      showDialog<AlertDialog>(
                          context: context,
                          builder: (context) 
                            return AlertDialog(
                              actions: [
                                FlatButton(
                                    onPressed: () ,
                                    child: Text('Edit')),
                                FlatButton(
                                    onPressed: () 
                                      setState(() 
                                        employeeRepository
                                            .delete(employee);
                                        Navigator.pop(context);
                                      );
                                    ,
                                    child: Text('Delete')),
                              ],
                              content: Text(employee.employeeName),
                            );
                          );
                    ,
                  );
                ,
              );
          ),
    ]),
  );

CRUD Operation in firestore

【讨论】:

以上是关于在 Flutter 列表视图中删除 Firestore 数据的主要内容,如果未能解决你的问题,请参考以下文章

flutter-firestore:如何从列表视图中删除 n 天前的项目

从列表视图中颤动删除项目

Flutter - 删除ListView中项目之间的空间

当我向列表视图添加元素时,如何在 Flutter 中更新列表视图?

从 ListView.builder 中返回自定义卡片和关闭(添加和删除到列表视图)

Flutter:如何在 Listview 中删除行之间的空间