[英]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 命令行界面来帮助处理嵌套删除。
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.