删除 Firestore 集合中的所有文档
Posted
技术标签:
【中文标题】删除 Firestore 集合中的所有文档【英文标题】:Deleting all documents in Firestore collection 【发布时间】:2018-05-31 08:15:49 【问题描述】:我正在寻找一种方法来清除整个集合。我看到有一个批量更新选项,但这需要我知道集合中的所有文档 ID。
我正在寻找一种方法来简单地删除集合中的每个文档。
谢谢!
编辑:下面的答案是正确的,我使用了以下内容:
func delete(collection: CollectionReference, batchSize: Int = 100)
// Limit query to avoid out-of-memory errors on large collections.
// When deleting a collection guaranteed to fit in memory, batching can be avoided entirely.
collection.limit(to: batchSize).getDocuments (docset, error) in
// An error occurred.
let docset = docset
let batch = collection.firestore.batch()
docset?.documents.forEach batch.deleteDocument($0.reference)
batch.commit _ in
self.delete(collection: collection, batchSize: batchSize)
【问题讨论】:
【参考方案1】:firebase CLI 中现在有一个选项可以删除整个 Firestore 数据库:
firebase firestore:delete --all-collections
【讨论】:
您可以通过 firebase firestore 获取更多信息:delete --help 运行firebase login
然后添加firebase firestore:delete --all-collections --project YOUR_PROJECT_NAME
小心不要在生产 Firestore 数据库中运行它,因为它会清除所有数据......除非这是您想要做的。
如何删除特定集合中的文档?这可以通过 CLI 实现吗?
@Isuru ...您可以使用firebase firestore:delete -r COLLECTION_NAME --project FB_PROJECT_NAME
递归删除集合中的所有文档(COLLECTION_NAME)【参考方案2】:
以下 javascript 函数将删除任何集合:
deleteCollection(path)
firebase.firestore().collection(path).listDocuments().then(val =>
val.map((val) =>
val.delete()
)
)
这是通过遍历每个文档并删除每个文档来实现的。
或者,您可以使用 Firestore 的批处理命令并使用以下功能一次性删除所有命令:
deleteCollection(path)
// Get a new write batch
var batch = firebase.firestore().batch()
firebase.firestore().collection(path).listDocuments().then(val =>
val.map((val) =>
batch.delete(val)
)
batch.commit()
)
【讨论】:
您的代码运行良好,来自 Firebase 云功能!但是 listDocuments() 不能从前端工作,并且 listDocuments() 不是 Firestore JavaScript 函数,据我所知。你有 listDocuments 文档的链接吗? @ThomasDavidKehoe 您可以在此处找到文档:github.com/googleapis/nodejs-firestore/blob/master/types/… 这是一个 NodeJS api,可能不适用于客户端 存在留下孤立子集合的风险。 listDocuments() 文档提到...“返回的文档引用可能包括对“缺失文档”的引用,即不存在文档但包含文档子集合的文档位置。” 请注意,如果您的集合包含超过 500 个文档,这将失败。A batched write can contain up to 500 operations
-batch docs。您可以通过将 listDocuments()
分成 500 个组来克服这个问题【参考方案3】:
没有 API 可以一次性删除整个集合(或其内容)。
来自Firestore documentation:
要删除 Cloud Firestore 中的整个集合或子集合,请检索集合或子集合中的所有文档并将其删除。如果您有较大的集合,您可能希望以较小的批次删除文档以避免内存不足错误。重复该过程,直到您删除整个集合或子集合。
该文档中甚至还有一个 Swift 示例,因此我建议您尝试一下。
Firebase CLI 允许您使用单个命令删除整个集合,但它只是调用 API 以批量删除该集合中的所有文档。如果这符合您的需求,我建议您查看(稀疏)documentation for the firestore:delete
command。
【讨论】:
但是文档说“不建议从 ios 客户端删除集合。” @FlorianWalther 将删除多个文档的代码放在服务器端。如果您想完全留在 Google 的服务范围内,可以使用例如 Cloud Functions。 查看下方@Kebabman 的评论,了解更新后的 cli 选项以删除所有集合(整个数据库中的所有数据)【参考方案4】:2020 年更新答案
您可以使用 Node JS 来做到这一点 - (注意他们使用了 process
这是一个著名的节点对象,在 Web javascript 中不可用)
查看由 firebase 托管的 Github 上的 thissn-p。我总是把那个页面固定在我的浏览器上;)
// [START delete_collection]
async function deleteCollection(db, collectionPath, batchSize)
const collectionRef = db.collection(collectionPath);
const query = collectionRef.orderBy('__name__').limit(batchSize);
return new Promise((resolve, reject) =>
deleteQueryBatch(db, query, resolve).catch(reject);
);
async function deleteQueryBatch(db, query, resolve)
const snapshot = await query.get();
const batchSize = snapshot.size;
if (batchSize === 0)
// When there are no documents left, we are done
resolve();
return;
// Delete documents in a batch
const batch = db.batch();
snapshot.docs.forEach((doc) =>
batch.delete(doc.ref);
);
await batch.commit();
// Recurse on the next process tick, to avoid
// exploding the stack.
process.nextTick(() =>
deleteQueryBatch(db, query, resolve);
);
// [END delete_collection]
【讨论】:
PS: 尝试使用 requestAnimationFrame 代替 process tick 并在 web javascript 上运行它;P ~ 说 匿名 像魅力一样工作,不需要从 Electron/Vue 应用程序内部替换 nextTick。【参考方案5】:我发现删除所有文档的最干净的方法。我唯一会使用这个函数的时候是在使用模拟器时,你可以简单地将函数粘贴到控制台中:
// Paste this in:
function clearCollection(path)
const ref = firestore.collection(path)
ref.onSnapshot((snapshot) =>
snapshot.docs.forEach((doc) =>
ref.doc(doc.id).delete()
)
)
// Use it like this:
clearCollection('layers')
如果您发现自己需要此代码反复将其保存为 Chrome 中的 sn-p,那么您可以轻松访问它,而不必一直将代码块粘贴到控制台中。您必须先运行 sn-p,然后才能从代码块访问它。 Documentation
【讨论】:
谢谢,在模拟器中,您可以在浏览器的控制台中运行它。【参考方案6】:在 VueJS 中测试
import db from '@/firebase/init'
let ref = db.collection('YOUR_COLLECTION_NAME')
db.collection(path).onSnapshot(snapshot =>
snapshot.docs.forEach(doc =>
ref.doc(doc.id).delete()
.catch(error =>
console.log(error)
)
)
)
【讨论】:
是的,已删除完整文档及其子集合。它在 VueJS 3 中也能完美运行。【参考方案7】:来自v4.10.0 的版本 现在可以使用此方法批量删除。
await firestore.recursiveDelete(firestore.collection('foo'));
它使用BulkWriter
来执行删除操作。
【讨论】:
【参考方案8】:上面的 THEODORE 对我有用。
db.collection("collectionName")
.get()
.then(res =>
res.forEach(element =>
element.ref.delete();
);
);
我没有直接回复他的评论的声誉。但除了他的解决方案之外,如果您需要使用此方法删除子集合,只需执行此操作即可。
db.collection(`collectionName/docID/subcollection`) //make sure to use backtics
.get()
.then(res =>
res.forEach(element =>
element.ref.delete();
);
);
如果 docID 是自动生成的,您可以在下面使用此方法。当用户单击全部清除按钮时,我用它来删除用户的通知。
db.collection(`collectionName/$variable/subcollection`)
.get()
.then((res) =>
res.forEach((element) =>
element.ref.delete();
);
);
变量可以是您设置 docID 的任何值。在我的例子中,它是 user.uid
【讨论】:
【参考方案9】:您必须获取所有文档,然后使用批处理批量删除它们 附言我更喜欢 try...catch 语法
let deleteInBatch = async (query, size = 100) =>
try
let batch = firestore().batch();
//get documents
let values = await query.get();
if(values.size>0)
values.foreach(value=>
batch.delete(value.ref);
)
//Delete the documents in bulk
batch.commit();
if(values.size>0)
//Recusively call the function again to finish
//deleting the rest of documents
deleteInBatch(query,size);
else
//exist function
return;
catch(err)
throw err;
【讨论】:
catch 块在这个例子中没有完成任何事情;捕获错误并立即抛出它与首先不捕获错误相同【参考方案10】:db.collection("collectionName")
.get()
.then(res =>
res.forEach(element =>
element.ref.delete();
);
);
【讨论】:
【参考方案11】:这是我采用的方法。虽然它工作正常,但我不确定它可能还有哪些其他隐藏问题。
function deleteCollection(collectionPath, batchSize=400)
let deletePromise = appFirestore.collection(collectionPath).listDocuments()
.then( function(docs)
let batch = appFirestore.batch();
if(docs.length <= batchSize)
docs.map( (doc) =>
batch.delete(doc);
);
batch.commit();
return true;
else
for (let i = 0; i < batchSize; i++)
batch.delete(docs[i]);
batch.commit();
return false;
)
.then( function(batchStatus)
return batchStatus ? true : deleteCollection(collectionPath, batchSize, debug);
)
.catch( function(error)
console.error(`Error clearing collections ($error)`);
return false;
);
return deletePromise;
【讨论】:
以上是关于删除 Firestore 集合中的所有文档的主要内容,如果未能解决你的问题,请参考以下文章
在 Firestore 中使用 Angular 删除集合中的文档