如何删除firestore安全规则历史记录

问题描述 投票:0回答:2

因此,我们偶然发现了存储的 Firestore 安全规则达到 2500 条配额限制的问题。在部署过程中,CLI 会询问我们是否要删除最旧的 10 条规则。因为我们想要自动化部署,对控制台提示做出反应并不完全是我们想要的。

有人知道如何批量删除完整的 firestore 安全规则历史记录,而不必通过 firebase 手动一一执行吗?

我无法从 Google 方面找到任何相关信息...

firebase google-cloud-firestore firebase-security
2个回答
3
投票

不确定是否可以一次删除所有安全规则,但根据文档,您可以通过创建删除最旧规则的逻辑来避免手动工作:

例如,要删除部署时间超过 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.`);

0
投票

我在使用@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");
  }
);

完成后记得删除/禁用,以避免意外删除规则!

© www.soinside.com 2019 - 2024. All rights reserved.