Bu sayfada, Güvenlik Kurallarını Yapılandırma ve Güvenlik Kuralları İçin Koşul Yazma bölümlerindeki kavramlar temel alınarak, istemcilerin bir dokümandaki bazı alanlarda işlem yapmasına izin veren ancak diğer alanlarda işlem yapmasına izin vermeyen kurallar oluşturmak için Cloud Firestore Security Rules öğesini nasıl kullanabileceğiniz açıklanmaktadır.
Bazen bir dokümandaki değişiklikleri doküman düzeyinde değil, alan düzeyinde kontrol etmek isteyebilirsiniz.
Örneğin, bir müşterinin doküman oluşturmasına veya değiştirmesine izin vermek ancak bu dokümandaki belirli alanları düzenlemesine izin vermemek isteyebilirsiniz. Ya da bir müşterinin oluşturduğu her dokümanın belirli bir alan grubunu içermesini zorunlu kılmak isteyebilirsiniz. Bu kılavuzda, Cloud Firestore Security Rules kullanarak bu görevlerden bazılarını nasıl gerçekleştirebileceğiniz açıklanmaktadır.
Yapay Zeka Desteği için yapay zeka istemi
Yapay zeka desteği için aşağıdaki istemi yapay zeka kodlama temsilcinize (ör. Android Studio'da Gemini, Antigravity, Claude Code, Codex ve Cursor) kopyalayın. İstemi özelleştirebilir ve temsilcinizle birlikte üzerinde çalışabilirsiniz. Ayrıntılı kurulum bilgileri için Firebase aracı becerileri sayfasını ziyaret edin.
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.
Yalnızca belirli alanlar için okuma erişimine izin verme
Kurallardaki okuma işlemleri doküman düzeyinde gerçekleştirilir. Ya belgenin tamamını alırsınız ya da hiçbir şey almazsınız. Kısmi bir dokümanı almanın yolu yoktur. Kullanıcıların bir dokümandaki belirli alanları okumasını engellemek için yalnızca güvenlik kurallarını kullanmak yeterli değildir.
Bir dokümanda bazı kullanıcılardan gizlemek istediğiniz belirli alanlar varsa en iyi yöntem, bu alanları ayrı bir dokümana yerleştirmektir. Örneğin, private alt koleksiyonunda şu şekilde bir doküman oluşturabilirsiniz:
/employees/{emp_id}
name: "Alice Hamilton",
department: 461,
start_date: <timestamp>
/employees/{emp_id}/private/finances
salary: 80000,
bonus_mult: 1.25,
perf_review: 4.2
Ardından, iki koleksiyon için farklı erişim düzeylerine sahip güvenlik kuralları ekleyebilirsiniz. Bu örnekte, yalnızca role özel kimlik doğrulama talebi Finance değerine eşit olan kullanıcıların bir çalışanın mali bilgilerini görüntüleyebileceğini belirtmek için özel kimlik doğrulama taleplerini kullanıyoruz.
service cloud.firestore {
match /databases/{database}/documents {
// Allow any logged in user to view the public employee data
match /employees/{emp_id} {
allow read: if request.resource.auth != null
// Allow only users with the custom auth claim of "Finance" to view
// the employee's financial data
match /private/finances {
allow read: if request.resource.auth &&
request.resource.auth.token.role == 'Finance'
}
}
}
}
Doküman oluştururken alanları kısıtlama
Kurallar şemasızdır. Yani bir dokümanın hangi alanları içerdiği konusunda veritabanı düzeyinde kısıtlama yoktur. Bu esneklik, geliştirme sürecini kolaylaştırabilir ancak istemcilerin yalnızca belirli alanları içeren veya diğer alanları içermeyen belgeler oluşturabilmesini sağlamak istediğiniz zamanlar olacaktır.
Bu kuralları, request.resource.data nesnesinin keys yöntemini inceleyerek oluşturabilirsiniz. Bu, istemcinin bu yeni dokümana yazmaya çalıştığı tüm alanların listesidir. Bu alan grubunu hasOnly() veya hasAny() gibi işlevlerle birleştirerek, bir kullanıcının kurallara ekleyebileceği belge türlerini kısıtlayan bir mantık ekleyebilirsiniz.
Yeni dokümanlarda belirli alanları zorunlu kılma
Bir restaurant koleksiyonunda oluşturulan tüm dokümanların en az bir name, location ve city alanı içerdiğinden emin olmak istediğinizi varsayalım. Bunu, yeni dokümandaki anahtar listesinde hasAll() yöntemini çağırarak yapabilirsiniz.
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to create a document only if that document contains a name
// location, and city field
match /restaurant/{restId} {
allow create: if request.resource.data.keys().hasAll(['name', 'location', 'city']);
}
}
}
Bu sayede restoranlar başka alanlarla da oluşturulabilir ancak istemci tarafından oluşturulan tüm dokümanların en azından bu üç alanı içermesi sağlanır.
Yeni dokümanlarda belirli alanları yasaklama
Benzer şekilde, yasaklı alanlar listesinde hasAny() kullanarak istemcilerin belirli alanları içeren dokümanlar oluşturmasını engelleyebilirsiniz. Bu yöntem, bir doküman bu alanlardan herhangi birini içeriyorsa doğru olarak değerlendirilir. Bu nedenle, belirli alanları yasaklamak için sonucu olumsuzlaştırmanız gerekir.
Örneğin, aşağıdaki örnekte istemcilerin average_score veya rating_count alanı içeren bir doküman oluşturmasına izin verilmez. Bu alanlar daha sonra bir sunucu çağrısı ile eklenir.
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to create a document only if that document does *not*
// contain an average_score or rating_count field.
match /restaurant/{restId} {
allow create: if (!request.resource.data.keys().hasAny(
['average_score', 'rating_count']));
}
}
}
Yeni dokümanlar için alan izin verilenler listesi oluşturma
Yeni belgelerde belirli alanları yasaklamak yerine, yalnızca yeni belgelerde açıkça izin verilen alanların listesini oluşturmak isteyebilirsiniz. Ardından, oluşturulan yeni belgelerin yalnızca bu alanları (veya bu alanların bir alt kümesini) içerdiğinden ve başka bir alan içermediğinden emin olmak için hasOnly() işlevini kullanabilirsiniz.
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to create a document only if that document doesn't contain
// any fields besides the ones listed below.
match /restaurant/{restId} {
allow create: if (request.resource.data.keys().hasOnly(
['name', 'location', 'city', 'address', 'hours', 'cuisine']));
}
}
}
Zorunlu ve isteğe bağlı alanları birleştirme
Güvenlik kurallarınızda hasAll ve hasOnly işlemlerini birleştirerek bazı alanları zorunlu kılıp diğerlerine izin verebilirsiniz. Örneğin, bu örnekte tüm yeni dokümanların name, location ve city alanlarını içermesi gerekir ve isteğe bağlı olarak address, hours ve cuisine alanlarına izin verilir.
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to create a document only if that document has a name,
// location, and city field, and optionally address, hours, or cuisine field
match /restaurant/{restId} {
allow create: if (request.resource.data.keys().hasAll(['name', 'location', 'city'])) &&
(request.resource.data.keys().hasOnly(
['name', 'location', 'city', 'address', 'hours', 'cuisine']));
}
}
}
Gerçek bir senaryoda, kodunuzu kopyalamamak ve isteğe bağlı ve zorunlu alanları tek bir listede daha kolay birleştirmek için bu mantığı bir yardımcı işleve taşımak isteyebilirsiniz:
service cloud.firestore {
match /databases/{database}/documents {
function verifyFields(required, optional) {
let allAllowedFields = required.concat(optional);
return request.resource.data.keys().hasAll(required) &&
request.resource.data.keys().hasOnly(allAllowedFields);
}
match /restaurant/{restId} {
allow create: if verifyFields(['name', 'location', 'city'],
['address', 'hours', 'cuisine']);
}
}
}
Güncelleme sırasında alanları kısıtlama
Yaygın bir güvenlik uygulaması, istemcilerin yalnızca bazı alanları düzenlemesine izin verip diğerlerini düzenlemesine izin vermemektir. Bunu yalnızca önceki bölümde açıklanan request.resource.data.keys() listesine bakarak yapamazsınız. Bu liste, güncellemeden sonra görünecek olan belgenin tamamını temsil eder ve bu nedenle istemcinin değiştirmediği alanları içerir.
Ancak diff() işlevini kullanırsanız request.resource.data ile güncellemeden önce veritabanındaki dokümanı temsil eden resource.data nesnesini karşılaştırabilirsiniz. Bu işlem, iki farklı harita arasındaki tüm değişiklikleri içeren bir nesne olan mapDiff nesnesini oluşturur.
Bu mapDiff'te affectedKeys() yöntemini çağırarak bir düzenlemede değiştirilen alanlar kümesini elde edebilirsiniz. Ardından, bu kümenin belirli öğeleri içerdiğinden (veya içermediğinden) emin olmak için hasOnly() veya hasAny() gibi işlevleri kullanabilirsiniz.
Bazı alanların değiştirilmesini engelleme
affectedKeys() tarafından oluşturulan kümede hasAny() yöntemini kullanıp sonucu reddederek, değiştirilmesini istemediğiniz alanları değiştirmeye çalışan tüm istemci isteklerini reddedebilirsiniz.
Örneğin, müşterilerin bir restoranla ilgili bilgileri güncellemesine izin vermek ancak ortalama puanını veya yorum sayısını değiştirmesini engellemek isteyebilirsiniz.
service cloud.firestore {
match /databases/{database}/documents {
match /restaurant/{restId} {
// Allow the client to update a document only if that document doesn't
// change the average_score or rating_count fields
allow update: if (!request.resource.data.diff(resource.data).affectedKeys()
.hasAny(['average_score', 'rating_count']));
}
}
}
Yalnızca belirli alanların değiştirilmesine izin verme
Değiştirilmesini istemediğiniz alanları belirtmek yerine, değiştirilmesini istediğiniz alanların listesini belirtmek için hasOnly() işlevini de kullanabilirsiniz. Yeni doküman alanlarına yazma işlemi, güvenlik kurallarınızda açıkça izin verene kadar varsayılan olarak engellendiğinden bu yöntem genellikle daha güvenli kabul edilir.
Örneğin, average_score ve rating_count alanlarına izin vermemek yerine, istemcilerin yalnızca name, location, city, address, hours ve cuisine alanlarını değiştirmesine izin veren güvenlik kuralları oluşturabilirsiniz.
service cloud.firestore {
match /databases/{database}/documents {
match /restaurant/{restId} {
// Allow a client to update only these 6 fields in a document
allow update: if (request.resource.data.diff(resource.data).affectedKeys()
.hasOnly(['name', 'location', 'city', 'address', 'hours', 'cuisine']));
}
}
}
Bu, uygulamanızın gelecekteki bir iterasyonunda restoran belgeleri telephone alanı içeriyorsa siz geri dönüp bu alanı güvenlik kurallarınızdaki hasOnly() listesine ekleyene kadar bu alanı düzenleme girişimlerinin başarısız olacağı anlamına gelir.
Alan türlerini zorunlu kılma
Kuralların şemasız olmasının bir diğer etkisi de belirli alanlarda hangi veri türlerinin depolanabileceği konusunda veritabanı düzeyinde bir yaptırım olmamasıdır. Ancak bunu güvenlik kurallarında is operatörüyle zorunlu kılabilirsiniz.
Örneğin, aşağıdaki güvenlik kuralı, bir yorumun score alanının tam sayı, headline, content ve author_name alanlarının dize, review_date alanının ise zaman damgası olmasını zorunlu kılar.
service cloud.firestore {
match /databases/{database}/documents {
match /restaurant/{restId} {
// Restaurant rules go here...
match /review/{reviewId} {
allow create: if (request.resource.data.score is int &&
request.resource.data.headline is string &&
request.resource.data.content is string &&
request.resource.data.author_name is string &&
request.resource.data.review_date is timestamp
);
}
}
}
}
is operatörü için geçerli veri türleri şunlardır: bool, bytes, float, int,
list, latlng, number, path, map, string ve timestamp. is operatörü constraint, duration, set ve map_diff veri türlerini de destekler ancak bunlar istemciler tarafından değil, güvenlik kuralları dilinin kendisi tarafından oluşturulduğundan çoğu pratik uygulamada nadiren kullanılır.
list ve map veri türleri, genel türleri veya tür bağımsız değişkenlerini desteklemez.
Başka bir deyişle, belirli bir alanın liste veya harita içermesini zorunlu kılmak için güvenlik kurallarını kullanabilirsiniz ancak bir alanın tüm tam sayıların veya tüm dizelerin listesini içermesini zorunlu kılamazsınız.
Benzer şekilde, bir listedeki veya haritadaki belirli girişler için tür değerlerini zorunlu kılmak üzere güvenlik kurallarını kullanabilirsiniz (sırasıyla köşeli parantez gösterimi veya anahtar adları kullanarak). Ancak bir haritadaki veya listedeki tüm üyelerin veri türlerini aynı anda zorunlu kılmanın bir kısayolu yoktur.
Örneğin, aşağıdaki kurallar bir dokümandaki tags alanının bir liste içerdiğinden ve ilk girişin bir dize olduğundan emin olur. Ayrıca product alanının, dize olan bir ürün adı ve tam sayı olan bir miktar içeren bir harita içerdiğinden emin olur.
service cloud.firestore {
match /databases/{database}/documents {
match /orders/{orderId} {
allow create: if request.resource.data.tags is list &&
request.resource.data.tags[0] is string &&
request.resource.data.product is map &&
request.resource.data.product.name is string &&
request.resource.data.product.quantity is int
}
}
}
}
Alan türleri, hem doküman oluşturulurken hem de güncellenirken zorunlu kılınmalıdır. Bu nedenle, güvenlik kurallarınızın hem oluşturma hem de güncelleme bölümlerinde çağırabileceğiniz bir yardımcı işlev oluşturmayı düşünebilirsiniz.
service cloud.firestore {
match /databases/{database}/documents {
function reviewFieldsAreValidTypes(docData) {
return docData.score is int &&
docData.headline is string &&
docData.content is string &&
docData.author_name is string &&
docData.review_date is timestamp;
}
match /restaurant/{restId} {
// Restaurant rules go here...
match /review/{reviewId} {
allow create: if reviewFieldsAreValidTypes(request.resource.data) &&
// Other rules may go here
allow update: if reviewFieldsAreValidTypes(request.resource.data) &&
// Other rules may go here
}
}
}
}
İsteğe bağlı alanlar için türleri zorunlu kılma
foo değerinin bulunmadığı bir dokümanda request.resource.data.foo çağrısı yapmanın hataya neden olacağını ve bu nedenle bu çağrıyı yapan tüm güvenlik kurallarının isteği reddedeceğini unutmayın. request.resource.data üzerinde get yöntemini kullanarak bu durumu çözebilirsiniz. get yöntemi, bir haritadan aldığınız alan mevcut değilse bu alan için varsayılan bir bağımsız değişken sağlamanıza olanak tanır.
Örneğin, inceleme dokümanlarında isteğe bağlı bir photo_url alanı ve isteğe bağlı bir tags alanı varsa ve bunların sırasıyla dize ve liste olduğunu doğrulamak istiyorsanız reviewFieldsAreValidTypes işlevini aşağıdaki gibi yeniden yazarak bunu yapabilirsiniz:
function reviewFieldsAreValidTypes(docData) {
return docData.score is int &&
docData.headline is string &&
docData.content is string &&
docData.author_name is string &&
docData.review_date is timestamp &&
docData.get('photo_url', '') is string &&
docData.get('tags', []) is list;
}
Bu, tags alanının bulunduğu ancak liste olmadığı dokümanları reddederken tags (veya photo_url) alanı içermeyen dokümanlara izin verir.
Kısmi yazma işlemlerine hiçbir zaman izin verilmez.
Cloud Firestore Security Rules ile ilgili son bir not: Bu araçlar, istemcinin bir dokümanda değişiklik yapmasına izin verir veya düzenlemenin tamamını reddeder. Belgenizdeki bazı alanlara yazma işlemlerini kabul ederken aynı işlemdeki diğerlerini reddeden güvenlik kuralları oluşturamazsınız.