Javascript 在Firestore中删除集合中的所有文档时返回所有文档
我正在使用下面的代码删除Firestore集合中的所有文档。我的问题是,如何执行一个函数,它将返回一个包含已删除文档的数组中的“deleteCollection”的结果(承诺)?我想把所有的文件都循环一遍。我当然可以先查询所有数据,循环遍历它,然后执行这个函数,但是数据会被读取两次 另一个选项是创建一个空的全局变量,delete函数在其中添加文档。但这有多安全?如果我删除两个巨大的集合,数组将填充两个不同的文档。这也不正确 我还试图修改“newpromise”返回,但函数参数只能包含resolve或reject,不能包含数组 所以我想要一个调用deleteCollection的函数,然后我想要循环删除的数据。当我只想读取一次数据时,这可能吗Javascript 在Firestore中删除集合中的所有文档时返回所有文档,javascript,node.js,firebase,promise,google-cloud-firestore,Javascript,Node.js,Firebase,Promise,Google Cloud Firestore,我正在使用下面的代码删除Firestore集合中的所有文档。我的问题是,如何执行一个函数,它将返回一个包含已删除文档的数组中的“deleteCollection”的结果(承诺)?我想把所有的文件都循环一遍。我当然可以先查询所有数据,循环遍历它,然后执行这个函数,但是数据会被读取两次 另一个选项是创建一个空的全局变量,delete函数在其中添加文档。但这有多安全?如果我删除两个巨大的集合,数组将填充两个不同的文档。这也不正确 我还试图修改“newpromise”返回,但函数参数只能包含resolv
function deleteCollection(db, collectionRef, batchSize) {
var query = collectionRef.limit(batchSize);
return new Promise(function(resolve, reject) {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
}
function deleteQueryBatch(db, query, batchSize, resolve, reject) {
query.get()
.then((snapshot) => {
if (snapshot.size == 0) {
return 0;
}
var batch = db.batch();
snapshot.docs.forEach(function(doc) {
batch.delete(doc.ref);
});
return batch.commit().then(function() {
return snapshot.size;
});
}).then(function(numDeleted) {
if (numDeleted <= batchSize) {
resolve();
return;
}
process.nextTick(function() {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
})
.catch(reject);
}
函数deleteCollection(db、collectionRef、batchSize){
var query=collectionRef.limit(batchSize);
返回新承诺(功能(解决、拒绝){
deleteQueryBatch(数据库、查询、批大小、解析、拒绝);
});
}
函数deleteQueryBatch(数据库、查询、批大小、解析、拒绝){
query.get()
。然后((快照)=>{
如果(snapshot.size==0){
返回0;
}
var batch=db.batch();
snapshot.docs.forEach(函数(doc){
批处理删除(文件编号ref);
});
返回batch.commit().then(函数()){
返回快照大小;
});
}).then(函数(numDeleted){
如果(numDeleted首先,避免:
(您可能还希望使用async
/await
语法,这将真正简化代码并使算法更易于理解:
async function deleteQueryBatch(db, query, batchSize) {
const snapshot = await query.get();
if (snapshot.size > 0) {
let batch = db.batch();
snapshot.docs.forEach(doc => { batch.delete(doc.ref); });
await batch.commit();
}
if (snapshot.size >= batchSize) {
// await new Promise(resolve => process.nextTick(resolve));
return deleteQueryBatch(db, query, batchSize);
}
}
创建一个空的全局变量,其中delete函数添加文档。但这有多安全?如果我删除两个大型集合,数组将填充两个不同的文档。这也不正确
不,不要这样做。只需将正在填充结果的数组作为参数通过递归调用传递,最后返回:
function deleteCollection(db, collectionRef, batchSize) {
return deleteQueryBatch(db, collectionRef.limit(batchSize), batchSize, []);
}
async function deleteQueryBatch(db, query, batchSize, results) {
const snapshot = await query.get();
if (snapshot.size > 0) {
let batch = db.batch();
snapshot.docs.forEach(doc => {
results.push(doc);
batch.delete(doc.ref);
});
await batch.commit();
}
if (snapshot.size >= batchSize) {
return deleteQueryBatch(db, query, batchSize, results);
} else {
return results;
}
}
避免使用!@Bergi我从Google文档中复制了代码:哎哟。他们肯定也应该避免使用它。文档中的一个文件bug在哪里呢?@Bergi我用这个链接联系了他们几次:他们通常反应很快(~1天)。但我没有Firebase帐户,该联系人页面需要有人登录。感谢您的回答。但是,我收到以下错误“未经处理的承诺拒绝(拒绝id:1):TypeError:无法读取未定义的属性“push”。我尝试登录该帐户并将[]更改为new Array(),但没有帮助。我尝试了结果。push(“测试”),我仍然得到那个错误。此外,deleteCollection返回一个void,因此我不确定如果TypeError消失了,我如何才能得到结果。我尝试在deleteQueryBatch之前添加'return',但这并不等待deleteQueryBatch的返回。@J.Doe啊,我忘记了一堆return
关键字并传递结果
into递归呼叫。感谢您抽出时间创建此精彩答案。我联系了支持热线。我希望他们会对我在电子邮件中添加的您的答案发表评论。谢谢!
async function deleteQueryBatch(db, query, batchSize) {
const snapshot = await query.get();
if (snapshot.size > 0) {
let batch = db.batch();
snapshot.docs.forEach(doc => { batch.delete(doc.ref); });
await batch.commit();
}
if (snapshot.size >= batchSize) {
// await new Promise(resolve => process.nextTick(resolve));
return deleteQueryBatch(db, query, batchSize);
}
}
function deleteCollection(db, collectionRef, batchSize) {
return deleteQueryBatch(db, collectionRef.limit(batchSize), batchSize, []);
}
async function deleteQueryBatch(db, query, batchSize, results) {
const snapshot = await query.get();
if (snapshot.size > 0) {
let batch = db.batch();
snapshot.docs.forEach(doc => {
results.push(doc);
batch.delete(doc.ref);
});
await batch.commit();
}
if (snapshot.size >= batchSize) {
return deleteQueryBatch(db, query, batchSize, results);
} else {
return results;
}
}