Структурирование правил безопасности Cloud Firestore

Cloud Firestore Security Rules позволяют управлять доступом к документам и коллекциям в базе данных. Гибкий синтаксис правил позволяет создавать правила, которые соответствуют любым операциям – от всех записей во всей базе данных до операций с определенным документом.

В этом руководстве описывается базовый синтаксис и структура правил безопасности. Объедините этот синтаксис с условиями правил безопасности, чтобы создать полные наборы правил.

Чтобы получить помощь от ИИ, скопируйте запрос ниже и вставьте его в свой ИИ-агент для программирования (например, Gemini в Android Studio, Antigravity, Claude Code, Codex или Cursor). Вы можете настроить запрос и повторить его с агентом. Подробные инструкции по установке вы найдете в статье Навыки агента Firebase.

Help me use Firebase in my app.
1. Make sure that **Firebase agent skills** are installed and updated. For Claude Code, Codex, or Cursor agents, help me install the Firebase plugin. For other agents, run `npx skills add firebase/agent-skills`. Always try to use **Firebase agent skills** for Firebase-related tasks.
2. Help me write, validate, and deploy Firebase Security Rules to protect my app's Firestore data.

Декларация сервиса и базы данных

Cloud Firestore Security Rules всегда начинается со следующей декларации:

service cloud.firestore {
  // The {database} wildcard allows the rules to reference any database,
  // but these rules are only active on databases where they are explicitly deployed.
  match /databases/{database}/documents {
    // ...
  }
}

Объявление service cloud.firestore ограничивает область действия правил, предотвращая конфликты между правилами Cloud Firestore Security Rules и правилами для других продуктов, таких как Cloud Storage.

Объявление match /databases/{database}/documents указывает, что правила должны соответствовать любой базе данных правил в проекте. Хотя проект может содержать до 100 баз данных, только первая созданная база данных назначается по умолчанию.

Cloud Firestore Security Rules применяются отдельно к каждой именованной базе данных в проекте. Это означает, что если вы создаете несколько баз данных, вам необходимо управлять правилами для каждой из них и развертывать их по отдельности. Подробные инструкции по развертыванию обновлений приведены в разделе Развертывание обновлений.

Основные правила чтения и записи

Базовые правила состоят из оператора match, указывающего путь к документу, и выражения allow, определяющего, когда разрешено чтение указанных данных:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

Все операторы match должны указывать на документы, а не на коллекции. Оператор match может указывать на определенный документ, как в match /cities/SF, или использовать подстановочные знаки, чтобы указывать на любой документ по указанному пути, как в match /cities/{city}.

В примере выше в операторе match используется синтаксис подстановочного знака {city}. Это означает, что правило применяется к любому документу в коллекции cities, например /cities/SF или /cities/NYC. При вычислении выражений allow в операторе match переменная city будет разрешена в название документа города, например SF или NYC.

Точечные операции

В некоторых ситуациях полезно разбить read и write на более мелкие операции. Например, ваше приложение может применять разные условия для создания и удаления документов. Или вы можете разрешить чтение отдельных документов, но запретить большие запросы.

Правило read можно разбить на get и list, а правило write – на create, update и delete:

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules

    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }
    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

Иерархические данные

Данные в правилах организованы в коллекции документов, и каждый документ может расширять иерархию за счет подколлекций. Важно понимать, как правила безопасности взаимодействуют с иерархическими данными.

Рассмотрим ситуацию, когда каждый документ в коллекции cities содержит подколлекцию landmarks. Правила безопасности применяются только к соответствующему пути, поэтому контроль доступа, заданный для коллекции cities, не применяется к подколлекции landmarks. Вместо этого напишите явные правила для управления доступом к подколлекциям:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

При вложении операторов match путь внутреннего оператора match всегда указывается относительно пути внешнего оператора match. Поэтому следующие наборы правил эквивалентны:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

Рекурсивные подстановочные знаки

Если вы хотите, чтобы правила применялись к иерархии произвольной глубины, используйте синтаксис рекурсивного подстановочного знака {name=**}. Пример:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

При использовании синтаксиса рекурсивного подстановочного знака переменная подстановочного знака будет содержать весь соответствующий сегмент пути, даже если документ находится в глубоко вложенной подколлекции. Например, приведенные выше правила будут соответствовать документу, расположенному по адресу /cities/SF/landmarks/coit_tower, а значением переменной document будет SF/landmarks/coit_tower.

Однако обратите внимание, что поведение рекурсивных подстановочных знаков зависит от версии правил.

Версия 1

По умолчанию в правилах безопасности используется версия 1. В версии 1 рекурсивные подстановочные знаки соответствуют одному или нескольким элементам пути. Они не соответствуют пустому пути, поэтому match /cities/{city}/{document=**} соответствует документам в подколлекциях, но не в коллекции cities, тогда как match /cities/{document=**} соответствует документам как в коллекции cities, так и в подколлекциях.

Рекурсивные подстановочные знаки должны находиться в конце оператора match.

Версия 2

Во второй версии правил безопасности рекурсивные подстановочные знаки соответствуют нулю или более элементам пути. match/cities/{city}/{document=**} соответствует документам в любых подколлекциях, а также документам в коллекции cities.

Чтобы использовать вторую версию, добавьте rules_version = '2'; в начале правил безопасности:

rules_version = '2';
service cloud.firestore {
 match /databases/{database}/documents {
   // Matches any document in the cities collection as well as any document
   // in a subcollection.
   match /cities/{city}/{document=**} {
     allow read, write: if <condition>;
   }
 }
}

В одном выражении соответствия может быть не более одного рекурсивного подстановочного знака, но в версии 2 его можно разместить в любом месте выражения. Пример:

rules_version = '2';
service cloud.firestore {
 match /databases/{database}/documents {
   // Matches any document in the songs collection group
   match /{path=**}/songs/{song} {
     allow read, write: if <condition>;
   }
 }
}

Если вы используете запросы к группам коллекций, вам необходимо использовать версию 2. Подробнее о том, как защитить запросы к группам коллекций…

Перекрывающиеся утверждения о совпадении

Документ может соответствовать нескольким инструкциям match. Если запросу соответствуют несколько выражений allow, доступ будет разрешен, если любое из условий имеет значение true:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

В приведенном выше примере все операции чтения и записи в коллекции cities будут разрешены, поскольку второе правило всегда имеет значение true, даже если первое правило всегда имеет значение false.

Ограничения правил безопасности

При работе с правилами безопасности учитывайте следующие ограничения:

Ограничение Сведения
Максимальное количество вызовов exists(), get() и getAfter() на запрос
  • 10 для запросов с одним документом и запросов с запросом.
  • 20 для чтения нескольких документов, транзакций и пакетной записи. Прежнее ограничение (10) также применяется к каждой операции.

    Например, вы создаете пакетный запрос на запись с тремя операциями записи, а правила безопасности используют два вызова доступа к документу для проверки каждой записи. В этом случае каждая запись использует 2 из 10 вызовов доступа, а пакетный запрос на запись – 6 из 20 вызовов доступа.

При превышении любого из этих ограничений возникает ошибка "Доступ запрещен".

Некоторые вызовы доступа к документам могут кешироваться и не учитываться в лимитах.

Максимальная глубина вложенности оператора match 10
Максимальная длина пути (в сегментах), допустимая в наборе вложенных операторов match. 100
Максимальное количество переменных для захвата пути в наборе вложенных операторов match 20
Максимальная глубина вызова функции 20
Максимальное количество аргументов функции 7
Максимальное количество привязок переменных let на функцию 10
Максимальное количество рекурсивных или циклических вызовов функций 0 (не разрешено)
Максимальное количество выражений, оцениваемых за один запрос 1000
Максимальный размер набора правил Для наборов правил действуют два ограничения по размеру:
  • Ограничение на размер текста набора правил, опубликованного из консоли Firebase или из CLI с помощью firebase deploy, составляет 256 КБ.
  • 250 КБ – ограничение на размер скомпилированного набора правил, который получается, когда Firebase обрабатывает исходный код и активирует его на сервере.

Дальнейшие действия