英文:
how do i delete a collection using functions in firebase?
问题
I want to delete a specific collection using a schedule.
const functions = require("firebase-functions");
const { initializeApp, applicationDefault, cert } = require('firebase-admin/app');
const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');
initializeApp();
const db = getFirestore();
exports.scheduledFunction = functions.pubsub.schedule('10 9 * * 1').timeZone('Asia/Seoul').onRun(
(context) => {
deleteCollection(db, "/ranking", 100);
}
)
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);
});
}
ERROR:
{
"insertId": "1debz6yf3nc8aa",
"jsonPayload": {
"@type": "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished",
"targetType": "PUB_SUB",
"status": "UNAUTHENTICATED",
"pubsubTopic": "projects/run-and-hit-32486390/topics/firebase-schedule-scheduledFunction-us-central1",
"jobName": "projects/run-and-hit-32486390/locations/asia-south1/jobs/firebase-schedule-scheduledFunction-us-central1"
},
"resource": {
"type": "cloud_scheduler_job",
"labels": {
"job_id": "firebase-schedule-scheduledFunction-us-central1",
"project_id": "run-and-hit-32486390",
"location": "asia-south1"
}
},
"timestamp": "2023-04-17T00:10:02.623192583Z",
"severity": "ERROR",
"logName": "projects/run-and-hit-32486390/logs/cloudscheduler.googleapis.com%2Fexecutions",
"receiveTimestamp": "2023-04-17T00:10:02.623192583Z"
}
It seems like an authentication issue, but it seems to work if I force it to run in the cloud.
I registered the schedule code and expected the data to be deleted at the set time, but an error occurred.
英文:
i want to delete a specific collection using a schedule.
const functions = require("firebase-functions");
const { initializeApp, applicationDefault, cert } = require('firebase-admin/app');
const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');
initializeApp();
const db = getFirestore();
exports.scheduledFunction = functions.pubsub.schedule('10 9 * * 1').timeZone('Asia/Seoul').onRun(
(context) => {
deleteCollection(db, "/ranking", 100);
}
)
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);
});
}
ERROR:
{
"insertId": "1debz6yf3nc8aa",
"jsonPayload": {
"@type": "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished",
"targetType": "PUB_SUB",
"status": "UNAUTHENTICATED",
"pubsubTopic": "projects/run-and-hit-32486390/topics/firebase-schedule-scheduledFunction-us-central1",
"jobName": "projects/run-and-hit-32486390/locations/asia-south1/jobs/firebase-schedule-scheduledFunction-us-central1"
},
"resource": {
"type": "cloud_scheduler_job",
"labels": {
"job_id": "firebase-schedule-scheduledFunction-us-central1",
"project_id": "run-and-hit-32486390",
"location": "asia-south1"
}
},
"timestamp": "2023-04-17T00:10:02.623192583Z",
"severity": "ERROR",
"logName": "projects/run-and-hit-32486390/logs/cloudscheduler.googleapis.com%2Fexecutions",
"receiveTimestamp": "2023-04-17T00:10:02.623192583Z"
}
it seems like an authentication issue, but it seems to work if i force it to run in the cloud.
i registered the schedule code and expected the data to be deleted at the set time, but an error occurred.
答案1
得分: 2
如@samthecodingman在评论中建议的那样,在deleteCollection(db, "/ranking", 100)
之前,您忘记添加return
语句。
另外,您可以查看文档,Firebase文档还提供了一个示例Firebase函数代码段,用于删除集合。
/**
* 启动递归删除给定路径的文档。
*
* 调用用户必须经过身份验证,并且在身份验证令牌上设置了自定义“admin”属性为true。
*
* 此删除不是原子操作,可能在仅删除一些文档后失败。
*
* @param {string} data.path 要删除的文档或集合路径。
*/
exports.recursiveDelete = functions
.runWith({
timeoutSeconds: 540,
memory: '2GB'
})
.https.onCall(async (data, context) => {
// 仅允许管理员用户执行此函数。
if (!(context.auth && context.auth.token && context.auth.token.admin)) {
throw new functions.https.HttpsError(
'permission-denied',
'必须是管理员用户才能启动删除操作。'
);
}
const path = data.path;
console.log(
`用户 ${context.auth.uid} 请求删除路径 ${path}`
);
// 对给定的文档或集合路径运行递归删除。
// 必须在functions配置中设置“token”,可以通过运行“firebase login:ci”命令在命令行中生成它。
await firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
force: true,
token: functions.config().fb.token
});
return {
path: path
};
});
注意:您将需要使用Firebase控制台项目设置中可以找到的同一Firebase项目的GCLOUD_PROJECT
ID。
英文:
As @samthecodingman suggested in the comments, you missed adding a return
statement before the line deleteCollection(db, "/ranking", 100)
.
Also Instead using your own code snippet to delete a collection using functions in a Firebase. You can check with this Documentation, where Firebase Docs has also provided a sample firebase function code snippet to delete the collection:
/**
* Initiate a recursive delete of documents at a given path.
*
* The calling user must be authenticated and have the custom "admin" attribute
* set to true on the auth token.
*
* This delete is NOT an atomic operation and it's possible
* that it may fail after only deleting some documents.
*
* @param {string} data.path the document or collection path to delete.
*/
exports.recursiveDelete = functions
.runWith({
timeoutSeconds: 540,
memory: '2GB'
})
.https.onCall(async (data, context) => {
// Only allow admin users to execute this function.
if (!(context.auth && context.auth.token && context.auth.token.admin)) {
throw new functions.https.HttpsError(
'permission-denied',
'Must be an administrative user to initiate delete.'
);
}
const path = data.path;
console.log(
`User ${context.auth.uid} has requested to delete path ${path}`
);
// Run a recursive delete on the given document or collection path.
// The 'token' must be set in the functions config, and can be generated
// at the command line by running 'firebase login:ci'.
await firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
force: true,
token: functions.config().fb.token
});
return {
path: path
};
});
Note : You will be requiring the GCLOUD_PROJECT
id of the same firebase project which you can find in the project settings of the firebase console.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论