You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore安全规则:如何禁止languages集合中code字段重复?

Fixing Duplicate Code Validation in Firestore Security Rules

Let's break down why your current rule isn't working and fix it step by step:

What's Wrong with Your Existing Rule

  • Incorrect Match Path: Your rule targets individual documents in the /languages/{language} collection, but your data structure shows you're storing multiple language entries inside a single document's languages field (a map of {code, name} objects). The rule isn't checking the right data structure at all.
  • Misused hasAny: The hasAny check you wrote references request.resource.code, which doesn't exist—request.resource refers to the entire document being written, and your structure nests code inside the languages map. Even if that reference was correct, the rule wouldn't scan all existing code values in the map.

The Correct Approach

To validate that all code values in the languages map are unique, you need to:

  1. Extract all code values from the incoming languages map.
  2. Check for duplicates by comparing the length of the code array to the size of a set created from that array (sets automatically remove duplicates, so matching lengths mean no repeats).

Updated Security Rule

Adjust the document path to match where your languages map is stored (e.g., /appSettings/{settings} in the example below):

service cloud.firestore {
  match /databases/{database}/documents {
    match /appSettings/{settings} {
      allow write: if 
        // Skip validation if `languages` isn't being updated
        !request.resource.data.keys().has('languages') ||
        (
          // Convert the `languages` map into an array of its values
          let languageEntries = request.resource.data.languages.values(),
          // Extract all `code` values into a single array
          let codes = languageEntries.map(entry => entry.code),
          // Ensure no duplicates exist (set size equals array length)
          codes.size() == codes.toSet().size()
        );
    }
  }
}

Key Explanations:

  • request.resource.data.languages.values() turns your languages map into an array of the nested {code, name} objects.
  • map(entry => entry.code) creates a flat array containing only the code values for easy comparison.
  • codes.toSet().size() gives the count of unique codes—if this matches the original array's length, there are no duplicates.

If You Intended Individual Language Documents

If you actually want to store each language as a separate document in the /languages collection:

  • The simplest fix is to use the code value as the document ID (e.g., /languages/Fr, /languages/En). Firestore automatically prevents duplicate document IDs in a collection, so this enforces uniqueness by design.
  • If you can't use code as the ID, you'd need a separate collection to track existing codes (e.g., /usedLanguageCodes/{code}) and validate against it in rules, but this requires transactional writes to keep the tracking collection in sync.

内容的提问来源于stack exchange,提问作者Taha Azzabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:48:28