因此,我们偶然发现了存储的 Firestore 安全规则达到 2500 条配额限制的问题。在部署过程中,CLI 会询问我们是否要删除最旧的 10 条规则。因为我们想要自动化部署,对控制台提示做出反应并不完全是我们想要的。
有人知道如何批量删除完整的 firestore 安全规则历史记录,而不必通过 firebase 手动一一执行吗?
我无法从 Google 方面找到任何相关信息...
不确定是否可以一次删除所有安全规则,但根据文档,您可以通过创建删除最旧规则的逻辑来避免手动工作:
例如,要删除部署时间超过 30 天的所有规则集:
const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS); const promises = []; allRulesets.forEach((rs) => { if (new Date(rs.crateTime) < thirtyDays) { promises.push(admin.securityRules().deleteRuleset(rs.name)); } }); await Promise.all(promises); console.log(`Deleted ${promises.length} rulesets.`);
我在使用@Farid 的解决方案时遇到了一些问题。如果有人想使用它,我将其写为云函数:
const admin = require("firebase-admin");
const { onRequest } = require("firebase-functions/v2/https");
exports.cleanRuleSets = onRequest(
{ memory: "256MiB", timeoutSeconds: 60 * 60 },
async (req, res) => {
// GATHER ALL RULESETS
let newToken;
let allRulesets = [];
while (true) {
let result;
if (!newToken) {
result = await admin.securityRules().listRulesetMetadata();
} else {
result = await admin.securityRules().listRulesetMetadata(100, newToken);
}
allRulesets.push(...result.rulesets);
newToken = result.nextPageToken;
if (!newToken) {
break;
}
}
// SET LOOK-BACK PERIOD. YOU MAY NEED TO SET THIS TO A HIGHER NUMBER AT FIRST AND THEN PROGRESSIVELY LOWER IF YOU HAVE A LOT OF RULESETS. I WAS GETTING RATE-LIMITED WITH TOO MANY API CALLS.
// I ALSO HIT THE MEMORY LIMIT OF 256MiB WITH TOO MANY RULESETS TO DELETE THE FIRST TIME I RAN IT, YOU CAN ADD MORE MEMORY IN THE CONFIG OBJECT
const daysToLookBack = 30; // MAKE SURE THIS NUMBER IS GREATER THAN THE DATE OF AT LEAST THREE DEPLOYMENTS TO AVOID DELETING CURRENT/TOO RECENT RULESETS
const daysInMilliseconds = daysToLookBack * 24 * 60 * 60 * 1000;
const daysAgo = new Date(Date.now() - daysInMilliseconds);
const promises = [];
allRulesets.forEach((el) => {
if (new Date(el.createTime) < daysAgo) {
// PUSH THE DELETE PROMISE TO TO PROMISES ARRAY FOR RULESETS OLDER THAN THE LOOK BACK PERIOD
if (el.name?.length > 0) {
promises.push(admin.securityRules().deleteRuleset(el.name));
}
}
});
// I GOT SOME ERRORS THAT WERE BLOCKING. USING ALLSETTLED TO CATCH ERRORS AND CONTINUE DELETING RULESETS.
const report = await Promise.allSettled(promises);
let successCount = 0;
let failedCount = 0;
report.forEach((el) => {
if (el.status === "rejected") {
failedCount++;
} else {
successCount++;
}
});
console.log(
`Successfully deleted ${promises.length} rulesets. Failed to delete ${failedCount} rulesets.`
);
res.status(200).send("Cleaned Rulesets");
}
);
完成后记得删除/禁用,以避免意外删除规则!