В этом руководстве на основе статьи Структурирование правил безопасности показано, как добавлять условия в Cloud Firestore Security Rules. Если вы не знакомы с основами Cloud Firestore Security Rules, ознакомьтесь с руководством по началу работы.
Основной элемент 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.
Аутентификация
Один из наиболее распространенных шаблонов правил безопасности – управление доступом на основе состояния аутентификации пользователя. Например, вы можете разрешить записывать данные только пользователям, выполнившим вход:
service cloud.firestore { match /databases/{database}/documents { // Allow the user to access documents in the "cities" collection // only if they are authenticated. match /cities/{city} { allow read, write: if request.auth != null; } } }
Ещё один распространенный шаблон – разрешить пользователям читать и записывать только собственные данные:
service cloud.firestore { match /databases/{database}/documents { // Make sure the uid of the requesting user matches name of the user // document. The wildcard expression {userId} makes the userId variable // available in rules. match /users/{userId} { allow read, update, delete: if request.auth != null && request.auth.uid == userId; allow create: if request.auth != null; } } }
Если в вашем приложении используется Firebase Authentication или Google Cloud Identity Platform, переменная request.auth содержит информацию об аутентификации клиента, запрашивающего данные.
Подробную информацию о request.auth можно найти в справочной документации.
Проверка данных
Многие приложения хранят информацию об управлении доступом в виде полей в документах базы данных. Cloud Firestore Security Rules может динамически разрешать или запрещать доступ на основе данных документа:
service cloud.firestore { match /databases/{database}/documents { // Allow the user to read data if the document has the 'visibility' // field set to 'public' match /cities/{city} { allow read: if resource.data.visibility == 'public'; } } }
Переменная resource относится к запрашиваемому документу, а resource.data – это карта всех полей и значений, хранящихся в документе. Подробную информацию о переменной resource можно найти в справочной документации.
При записи данных может потребоваться сравнить входящие данные с существующими.
В этом случае, если ваш набор правил разрешает ожидающую запись, переменная request.resource содержит будущее состояние документа. Для операций update, которые изменяют только подмножество полей документа, переменная request.resource будет содержать ожидающее состояние документа после операции. Чтобы предотвратить нежелательные или несогласованные обновления данных, вы можете проверить значения полей в request.resource:
service cloud.firestore { match /databases/{database}/documents { // Make sure all cities have a positive population and // the name is not changed match /cities/{city} { allow update: if request.resource.data.population > 0 && request.resource.data.name == resource.data.name; } } }
Как получить доступ к другим документам
С помощью функций get() и exists() правила безопасности могут оценивать входящие запросы по другим документам в базе данных. Функции get() и exists() ожидают полные пути к документам. Если вы используете переменные для создания путей для get() и exists(), вам нужно явно экранировать переменные с помощью синтаксиса $(variable).
В примере ниже переменная database захватывается оператором соответствия match /databases/{database}/documents и используется для формирования пути:
service cloud.firestore { match /databases/{database}/documents { match /cities/{city} { // Make sure a 'users' document exists for the requesting user before // allowing any writes to the 'cities' collection allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid)); // Allow the user to delete cities if their user document has the // 'admin' field set to 'true' allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true; } } }
Для записи можно использовать функцию getAfter(), чтобы получить доступ к состоянию документа после завершения транзакции или пакета записей, но до фиксации транзакции или пакета. Как и get(), функция getAfter() принимает полный путь к документу. С помощью getAfter() можно определить наборы записей, которые должны выполняться вместе как транзакция или пакет.
Как получить доступ к лимитам на звонки
Для каждого набора правил действует ограничение на количество вызовов доступа к документу:
- 10 для запросов с одним документом и запросов с запросом.
-
20 для чтения нескольких документов, транзакций и пакетной записи. Предыдущее ограничение (10) также применяется к каждой операции.
Например, вы создаете пакетный запрос на запись с тремя операциями записи, а правила безопасности используют два вызова доступа к документам для проверки каждой записи. В этом случае каждая запись использует 2 из 10 вызовов доступа, а пакетный запрос на запись – 6 из 20 вызовов доступа.
При превышении любого из этих ограничений возникает ошибка "Доступ запрещен". Некоторые вызовы доступа к документам могут кешироваться и не учитываться в лимитах.
Подробное объяснение того, как эти ограничения влияют на транзакции и пакетные записи, см. в руководстве по защите атомарных операций.
Доступ к звонкам и цены
При использовании этих функций в базе данных выполняется операция чтения, а это значит, что с вас будет взиматься плата за чтение документов, даже если ваши правила отклонят запрос. Подробную информацию о ценах вы найдете в статье Цены на правила.
Пользовательские функции
По мере усложнения правил безопасности вы можете захотеть обернуть наборы условий в функции, которые можно повторно использовать в наборе правил. Правила безопасности поддерживают пользовательские функции. Синтаксис пользовательских функций похож на JavaScript, но функции правил безопасности пишутся на предметно-ориентированном языке, у которого есть важные ограничения:
- Функции могут содержать только один оператор
return. Они не могут содержать дополнительную логику. Например, они не могут выполнять циклы или вызывать внешние сервисы. - Функции могут автоматически получать доступ к функциям и переменным из области видимости, в которой они определены. Например, функция, определенная в области видимости
service cloud.firestore, имеет доступ к переменнойresourceи встроенным функциям, таким какget()иexists(). - Функции могут вызывать другие функции, но не могут быть рекурсивными. Общая глубина стека вызовов ограничена 10.
- В правилах версии
v2функции могут определять переменные с помощью ключевого словаlet. Функции могут иметь до 10 привязок let, но должны заканчиваться оператором return.
Функция определяется с помощью ключевого слова function и принимает ноль или более аргументов. Например, вы можете объединить два типа условий, использованных в примерах выше, в одну функцию:
service cloud.firestore { match /databases/{database}/documents { // True if the user is signed in or the requested data is 'public' function signedInOrPublic() { return request.auth.uid != null || resource.data.visibility == 'public'; } match /cities/{city} { allow read, write: if signedInOrPublic(); } match /users/{user} { allow read, write: if signedInOrPublic(); } } }
Использование функций в правилах безопасности упрощает их поддержку по мере усложнения правил.
Правила – это не фильтры
После того, как вы защитите свои данные и начнете писать запросы, помните, что правила безопасности не являются фильтрами. Вы не можете написать запрос для всех документов в коллекции и ожидать, что правила вернут только те документы, к которым у текущего клиента есть разрешение на доступ.
Рассмотрим следующее правило безопасности:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
Отклонено. Это правило отклоняет следующий запрос, поскольку в набор результатов могут входить документы, в которых visibility не равно public:
Сайт
db.collection("cities").get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
});Разрешено. Это правило разрешает следующий запрос, поскольку условие where("visibility", "==", "public") гарантирует, что набор результатов соответствует условию правила:
Сайт
db.collection("cities").where("visibility", "==", "public").get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
});Правила безопасности оценивают каждый запрос по его потенциальному результату и отклоняют запрос, если он может вернуть документ, на чтение которого у клиента нет разрешения. Запросы должны соответствовать ограничениям, установленным вашими правилами безопасности. Подробнее о правилах безопасности и запросах…
Дальнейшие действия
- Подробнее о том, как правила безопасности влияют на запросы…
- Подробнее о том, как структурировать правила безопасности…
- Ознакомьтесь со справочником по правилам безопасности.
- Если ваши приложения используют Cloud Storage for Firebase, узнайте, как писать условия Cloud Storage Security Rules, которые получают доступ к документам Cloud Firestore.