简体   繁体   English

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

[英]How to Delete all documents in collection in Firestore with Flutter

I have a firestore database.我有一个 Firestore 数据库。 My project plugins:我的项目插件:

cloud_firestore: ^0.7.4 firebase_storage: ^1.0.1 cloud_firestore:^0.7.4 firebase_storage:^1.0.1

This have a collection "messages" with a multiple documents.这有一个包含多个文档的集合“消息”。 I need to delete all documents in the messages collection.我需要删除消息集合中的所有文档。 But this code fail:但是这段代码失败了:

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

but delete is not define但删除未定义

how is the correct syntax?正确的语法是怎样的?

Ah.啊。 The first answer is almost correct.第一个答案几乎是正确的。 The issue has to do with the map method in dart and how it works with Futures.这个问题与 dart 中的 map 方法以及它如何与 Futures 一起工作有关。 Anyway, try using a for loop instead like so and you should be good:无论如何,尝试使用 for 循环而不是这样,你应该会很好:

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

As stated in Firestore docs , there isn't currently an operation that atomically deletes a collection.如 Firestore 文档中所述,目前没有原子删除集合的操作。

You'll need to get all the documents, and loop through them to delete each of them.您需要获取所有文档,并遍历它们以删除每个文档。

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

Note that this will only remove the messages collection.请注意,这只会删除messages集合。 If there are subcollections in this path they will remain in Firestore.如果此路径中有子集合,它们将保留在 Firestore 中。 The docs also has a cloud function also integration with a Callable function that uses the Firebase Command Line Interface to help with dealing nested deletion.该文档还有一个云函数,该函数还与一个 Callable 函数集成,该函数使用 Firebase 命令行界面来帮助处理嵌套删除。

Update 2021: 2021 年更新:

Iterate over the QueryDocumentSnapshot , get the DocumentReference and call delete on it.遍历QueryDocumentSnapshot ,获取DocumentReference并对其调用delete

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

The reason why delete does not work because that function is meant to delete documents not collections so instead of using: 之所以无法执行删除操作,是因为该功能旨在删除文档而不是集合,因此不使用:

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

use this: 用这个:

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

Delete All Documents from firestore Collection one by one:将 firestore Collection 中的所有文档一一删除:

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 {
        }
    }
});

I think this might help for multiple collections in any document reference我认为这可能有助于任何文档参考中的多个集合

// 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('====================================');
        }
      });
    }
  }

In the latest version of the firebase, you can do following.在最新版本的 firebase 中,您可以执行以下操作。

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

In case, if you don't want to use stream (because it will keep deleting until you cancel the subscription).以防万一,如果您不想使用流(因为它会一直删除,直到您取消订阅)。 You can go with future delete.您可以继续删除。 Here is the snippet:这是片段:

final collectionRef = FirebaseFirestore.instance.collection('collection_name');
final futureQuery = collectionRef.get();
await futureQuery.then((value) => value.docs.forEach((element) {
      element.reference.delete();
}));
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();

        });
      }
    });

Really surprised nobody has recommended to batch these delete requests yet.真的很惊讶还没有人建议批量处理这些删除请求。

A batch of writes completes atomically and can write to multiple documents.一批写入以原子方式完成,可以写入多个文档。 Batched Writes are completely atomic and unlike Transaction they don't depend on document modification in which they are writing to.批量写入是完全原子的,与事务不同,它们不依赖于写入的文档修改。 Batched writes works fine even when the device is offline.即使设备离线,批量写入也能正常工作。

A nice solution would be something like:一个不错的解决方案是这样的:

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

Remember you can combine delete with other tasks too.请记住,您也可以将delete与其他任务结合使用。 An example of how you might replace everything in a collection with a new set of data:如何用一组新数据替换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();
}

users<Collection> -> userId<Document> -> transactions<Collection> -> List(doc - to be deleted) let's assume this as the collection we will talk about users<Collection> -> userId<Document> -> transactions<Collection> -> List(doc - to be deleted)让我们假设这是我们要讨论的集合

To delete all documents in a collection along with the collection itself, you need to first delete the List(doc - to be deleted) in a batch要删除集合中的所有文档以及集合本身,您需要先批量删除List(doc - to be deleted)

// batch to delete all transactions associated with a user doc
    final WriteBatch batch = FirebaseFirestore.instance.batch();

    // Delete the doc in [FirestoreStrings.transactionCollection] collection
    await _exchangesCollection
        .doc(docId)
        .collection("transaction")
        .get()
        .then((snap) async {
      for (var doc in snap.docs) {
        batch.delete(doc.reference);
      }

      // execute the batch
      await batch.commit();

and then delete the doc userId<Document> which holds the transactions<Collection>然后删除保存交易的文档userId<Document> transactions<Collection>

By this way you might have to get rid of the entire userId<Document> itself, but its the only way around to get rid of it completely.通过这种方式,您可能必须摆脱整个userId<Document>本身,但这是完全摆脱它的唯一方法。

else you can skip the second step of deleting the doc to get rid of the collection, which is totally fine as the collection ref in a doc serves just as the field of the doc.否则您可以跳过删除文档的第二步以摆脱集合,这完全没问题,因为文档中的集合引用就像文档的字段一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Firestore -Flutter 中将所有文档从一个集合复制到另一个集合? - How to copy all documents from one collection to other in Firestore -Flutter? 如何从Firestore中的集合中检索所有文档? - How to retrieve all documents from a collection in Firestore? 遍历集合中的所有firestore文档并在flutter中更新它们 - Loop through all firestore documents in a collection AND update them in flutter 从firestore中where条件的子集合的所有文档中删除数据 - Delete data from all the documents of sub collection with where condition in firestore 如何使用 javascript 删除 Firestore 上的所有文档 - how to delete all documents on firestore using javascript Firestore Flutter 如何获取集合中所有文档及其数据的列表? - Firestore Flutter How to get a list all the documents and its data inside a collection? 如何删除 Firestore 中所有文档的字段 - How to delete fields for all documents in Firestore 如何从 Cloud Firestore 删除集合及其所有子集合和文档 - How to delete a collection with all its sub-collections and documents from Cloud Firestore 如何获取 Firestore 集合中所有文档的子集合的特定文档? - How to get specific Documents of a Subcollection of all Documents in a Collection in Firestore? Firestore 不返回集合的所有文档 - Firestore returning not all documents for a collection
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM