如何使用 Flutter 在 Firestore 中删除集合中的所有文档

Posted

技术标签:

【中文标题】如何使用 Flutter 在 Firestore 中删除集合中的所有文档【英文标题】:How to Delete all documents in collection in Firestore with Flutter 【发布时间】:2019-04-04 23:35:45 【问题描述】:

我有一个 Firestore 数据库。我的项目插件:

cloud_firestore:^0.7.4 firebase_storage: ^1.0.1

这有一个包含多个文档的集合“消息”。 我需要删除消息集合中的所有文档。但是这段代码失败了:

Firestore.instance.collection('messages').delete();

但删除没有定义

语法如何正确?

【问题讨论】:

【参考方案1】:

啊。第一个答案几乎正确。这个问题与 dart 中的 map 方法以及它如何与 Futures 一起使用有关。无论如何,尝试像这样使用 for 循环,你应该会很好:

firestore.collection('messages').getDocuments().then((snapshot) 
  for (DocumentSnapshot ds in snapshot.documents)
    ds.reference.delete();
  );
);

【讨论】:

我意识到我的答案很模糊,但我可以根据经验告诉您,使用 map 在处理期货时无法正常工作。使用 for 循环可以解决我目前遇到的所有问题。 如果你意识到你的答案是模糊的,也许你可以参考颤振文档来更新它? (如果他们在任何地方提到这个问题/错误/功能......) 明白。但是答案很模糊,只是因为我没有时间深入研究文档以找出为什么会这样。我和这个问题的人有同样的问题,并通过简单地尝试找到了解决方案。所以我只是试图根据我所知道的工作经验来帮助某人。 完全没问题 :) 只是想指出这样的参考可以帮助您的答案不那么含糊。 这个答案给我带来了问题。运行后由于某种原因它不断删除新条目,就好像查询卡在缓存中的某个地方一样。【参考方案2】:

正如 Firestore docs 中所述,目前没有原子删除集合的操作。

您需要获取所有文档,并遍历它们以删除它们。

firestore.collection('messages').getDocuments().then((snapshot) 
  for (DocumentSnapshot doc in snapshot.documents) 
    doc.reference.delete();
  );
);

请注意,这只会删除 messages 集合。如果此路径中有子集合,它们将保留在 Firestore 中。该文档还有一个云函数,它还与一个 Callable 函数集成,该函数使用 Firebase 命令行界面来帮助处理嵌套删除。

【讨论】:

你好,代码运行没有任何错误,但是集合没有被删除,代码不起作用。谢谢 更新了答案,基本上是@Ryan Newell 所说的。【参考方案3】:

2021 年更新:

遍历QueryDocumentSnapshot,获取DocumentReference 并调用delete

var collection = FirebaseFirestore.instance.collection('collection');
var snapshots = await collection.get();
for (var doc in snapshots.docs) 
  await doc.reference.delete();

【讨论】:

【参考方案4】:

真的很惊讶还没有人建议批量删除这些删除请求。

一批写入以原子方式完成,可以写入多个文档。批量写入是完全原子的,与事务不同,它们不依赖于写入的文档修改。即使设备离线,批量写入也能正常工作。

一个不错的解决方案是这样的:

Future<void> deleteAll() async 
  final collection = await FirebaseFirestore.instance
      .collection("posts")
      .get();

  final batch = FirebaseFirestore.instance.batch();

  for (final doc in collection.docs) 
    batch.delete(doc.reference);
  
  
  return batch.commit();

请记住,您也可以将delete 与其他任务结合使用。如何用一组新数据替换 collection 中的所有内容的示例:

Future<void> replaceAll(List<Posts> newPosts) async 
  final collection = await FirebaseFirestore.instance
      .collection("posts")
      .get();

  final batch = FirebaseFirestore.instance.batch();

  for (final doc in collection.docs) 
    batch.delete(doc.reference);
  

  for (final post in posts) 
    batch.set(postRef().doc(post.id), post);
  

  batch.commit();

【讨论】:

【参考方案5】:

从firestore集合中一一删除所有文档:

db.collection("users").document(userID).collection("cart")
    .get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() 
@Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) 
        if (task.isSuccessful()) 
            for (QueryDocumentSnapshot document : task.getResult())                                   
                db.collection("users").document(userID).
                    collection("cart").document(document.getId()).delete();
            
         else 
        
    
);

【讨论】:

【参考方案6】:

我认为这可能有助于任何文档参考中的多个集合

// add $documentReference that contains / may contains the $collectionsList
_recursiveDeleteDocumentNestedCollections(
      DocumentReference documentReference, List<String> collectionsList) async 
    // check if collection list length > 0
    if (collectionsList.length > 0) 
      // this line provide an async forEach and wait until it finished
      Future.forEach(collectionsList, (collectionName) async 
        // get the collection reference inside the provided document
        var nfCollectionRef = documentReference.collection(collectionName);
        try 
          // get nested collection documents
          var nestedDocuemtnsQuery = await nfCollectionRef.getDocuments();
          // loop through collection documents 
          Future.forEach(nestedDocuemtnsQuery.documents, (DocumentSnapshot doc) async 
            // recursive this function till the last nested collections documents
            _recursiveDeleteDocumentNestedCollections(
                doc.reference, collectionsList);
            // delete the main document
            doc.reference.delete();
          );
         catch (e) 
          print('====================================');
          print(e);
          print('====================================');
        
      );
    
  

【讨论】:

【参考方案7】:

在最新版本的 firebase 中,您可以进行以下操作。

_collectionReference.snapshots().forEach((element) 
        for (QueryDocumentSnapshot snapshot in element.docs) 
          snapshot.reference.delete();
        
      );

【讨论】:

尝试使用它来删除集合中的所有文档,但对我来说,它会在添加文档后立即删除。【参考方案8】:

以防万一,如果您不想使用流(因为它会一直删除,直到您取消订阅)。您可以使用将来的删除。这是sn-p:

final collectionRef = FirebaseFirestore.instance.collection('collection_name');
final futureQuery = collectionRef.get();
await futureQuery.then((value) => value.docs.forEach((element) 
      element.reference.delete();
));

【讨论】:

【参考方案9】:
Firestore.instance.collection("chatRoom").document(chatRoomId).collection("chats").getDocuments().then((value) 
      for(var data in value.docs)
        Firestore.instance.collection("chatRoom").document(chatRoomId).collection("chats")
            .document(data.documentID).delete().then((value) 
          Firestore.instance.collection("chatRoom").document(chatRoomId).delete();

        );
      
    );

【讨论】:

虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。

以上是关于如何使用 Flutter 在 Firestore 中删除集合中的所有文档的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flutter 在 Firestore 中删除集合中的所有文档

如何在 Flutter Web 上使用 StreamBuilder 和 Firestore?

如何在 Firebase + Firestore + Flutter 中使用 StreamBuilder 将所有子集合数据获取到 Widget

如何在flutter的firestore中使用uid更新用户数据

如何在flutter中获取firestore文档的documentid?

如何使用flutter cloud_firestore包传递firestore auth token