Uygulamanızı oluştururken Cloud Firestore veritabanınıza erişimi kilitlemek isteyebilirsiniz. Fakat lansmandan önce daha incelikli Cloud Firestore Güvenlik Kurallarına ihtiyacınız olacak. Cloud Firestore emülatörü ile, uygulamanızın genel özelliklerini ve davranışını prototip oluşturma ve test etmenin yanı sıra, Cloud Firestore Güvenlik Kurallarınızın davranışını kontrol eden birim testleri yazabilirsiniz.
Hızlı başlangıç kılavuzu
Basit kurallar içeren birkaç temel test durumu için hızlı başlangıç örneğini deneyin.
Cloud Firestore Güvenlik Kurallarını Anlama
Mobil ve web istemci kitaplıklarını kullanırken sunucusuz kimlik doğrulama, yetkilendirme ve veri doğrulama için Firebase Authentication ve Cloud Firestore Güvenlik Kuralları'nı uygulayın.
Cloud Firestore Güvenlik Kuralları iki parçadan oluşur:
- Veritabanınızdaki dokümanları tanımlayan
match
ifadesi. - Bu dokümanlara erişimi kontrol eden bir
allow
ifadesi.
Firebase Authentication, kullanıcıların kimlik bilgilerini doğrular, kullanıcı ve rol tabanlı erişim sistemleri için temel oluşturur.
Cloud Firestore mobil/web istemci kitaplığından gelen her veritabanı isteği, veri okunmadan veya yazılmadan önce güvenlik kurallarınıza göre değerlendirilir. Kurallar, belirtilen belge yollarından herhangi birine erişimi reddederse isteğin tamamı başarısız olur.
Cloud Firestore Güvenlik Kurallarını kullanmaya başlama bölümünde Cloud Firestore Güvenlik Kuralları hakkında daha fazla bilgi edinebilirsiniz.
Emülatörü yükleme
Cloud Firestore emülatörünü yüklemek için Firebase CLI kullanın ve aşağıdaki komutu çalıştırın:
firebase setup:emulators:firestore
Emülatörü çalıştırma
Çalışma dizininizde bir Firebase projesini başlatarak başlayın. Bu, Firebase CLI'ı kullanırken yaygın olarak yapılan bir ilk adımdır.
firebase init
Aşağıdaki komutu kullanarak emülatörü başlatın. Emülatör siz işlemi sonlandırana kadar çalışır:
firebase emulators:start --only firestore
Çoğu durumda emülatörü başlatmak, bir test paketi çalıştırmak ve testler çalıştırıldıktan sonra emülatörü kapatmak istersiniz. Bu işlemi emulators:exec
komutunu kullanarak kolayca yapabilirsiniz:
firebase emulators:exec --only firestore "./my-test-script.sh"
Başlatıldığında emülatör varsayılan bir bağlantı noktası (8080) üzerinde çalışmayı dener. firebase.json
dosyanızın "emulators"
bölümünü değiştirerek emülatör bağlantı noktasını değiştirebilirsiniz:
{ // ... "emulators": { "firestore": { "port": "YOUR_PORT" } } }
Emülatörü çalıştırmadan önce
Emülatörü kullanmaya başlamadan önce aşağıdakileri göz önünde bulundurun:
- Emülatör, başlangıçta
firebase.json
dosyanızınfirestore.rules
alanında belirtilen kuralları yükler. Cloud Firestore Güvenlik Kurallarınızı içeren yerel bir dosyanın adını bekler ve bu kuralları tüm projelere uygular. Yerel dosya yolunu belirtmez veya aşağıda açıklandığı gibiloadFirestoreRules
yöntemini kullanmazsanız emülatör tüm projeleri açık kurallara sahip olarak değerlendirir. - Firebase SDK'larının çoğu doğrudan emülatörlerle çalışsa da Güvenlik Kuralları'nda
auth
ile alay etmeyi sadece@firebase/rules-unit-testing
kitaplığı destekler ve birim testlerini çok daha kolay hale getirir. Ayrıca kitaplık, aşağıda listelendiği gibi tüm verileri temizleme gibi emülatöre özgü birkaç özelliği destekler. - Emülatörler ayrıca istemci SDK'ları aracılığıyla sağlanan üretim Firebase Auth jetonlarını da kabul edecek ve kuralları uygun şekilde değerlendirecektir. Böylece uygulamanız, entegrasyon ve manuel testlerde doğrudan emülatörlere bağlanabilecektir.
Yerel birim testlerini çalıştırma
v9 JavaScript SDK ile yerel birim testleri çalıştırma
Firebase, hem kendi sürüm 9 JavaScript SDK'sı hem de sürüm 8 SDK'sı ile bir Güvenlik Kuralları birimi test kitaplığı dağıtır. Kitaplık API'leri önemli ölçüde farklıdır. Emülatörlere bağlanmak için daha az kurulum gerektiren ve daha basit olan v9 test kitaplığını öneririz. Böylece üretim kaynaklarının yanlışlıkla kullanılmaması sağlanır. Geriye dönük uyumluluk için v8 test kitaplığını kullanıma sunmaya devam ediyoruz.
- v9 SDK'sında yaygın test yöntemleri ve yardımcı program işlevleri
- v9 SDK'sında emülatöre özel test yöntemleri
Yerel olarak çalışan emülatörle etkileşim kurmak için @firebase/rules-unit-testing
modülünü kullanın. Zaman aşımları veya ECONNREFUSED
hataları alıyorsanız emülatörün gerçekten çalışıp çalışmadığını tekrar kontrol edin.
async/await
notasyonunu kullanabilmek için Node.js'nin yeni bir sürümünü kullanmanızı önemle tavsiye ederiz. Test etmek isteyebileceğiniz davranışların neredeyse tamamı eşzamansız işlevleri kapsar ve test modülü, Promise tabanlı kodla çalışacak şekilde tasarlanmıştır.
v9 Kural Birimi Testi kitaplığı emülatörlerden her zaman haberdar olur ve üretim kaynaklarınıza hiçbir zaman dokunmaz.
Kitaplığı, v9 modüler içe aktarma ifadelerini kullanarak içe aktarırsınız. Örnek:
import {
assertFails,
assertSucceeds,
initializeTestEnvironment
} from "@firebase/rules-unit-testing"
// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.
İçe aktarma işleminden sonra, birim testlerinin uygulanması şunları içerir:
initializeTestEnvironment
çağrısı ile birRulesTestEnvironment
oluşturma ve yapılandırma.- Kuralları tetiklemeden test verilerini ayarlamak için bunları geçici olarak atlamanızı sağlayan bir kolaylık yöntemi kullanın
RulesTestEnvironment.withSecurityRulesDisabled
. RulesTestEnvironment.cleanup()
veyaRulesTestEnvironment.clearFirestore()
gibi test verilerini ve ortamını temizlemek için çağrılar içeren kancalarla birlikte test paketi ve test başına öncesi/sonrası ayarlama.RulesTestEnvironment.authenticatedContext
veRulesTestEnvironment.unauthenticatedContext
kullanarak kimlik doğrulama durumlarını taklit eden test durumları uygulama.
Sık kullanılan yöntemler ve fayda işlevleri
Ayrıca v9 SDK'sındaki emülatöre özel test yöntemlerine de bakın.
initializeTestEnvironment() => RulesTestEnvironment
Bu işlev, kural birimi testi için bir test ortamı başlatır. Test kurulumu için önce bu işlevi çağırın. Başarılı yürütme için emülatörlerin çalışması gerekir.
İşlev, proje kimliği ve emülatör yapılandırma ayarlarından oluşan TestEnvironmentConfig
tanımlayan isteğe bağlı bir nesneyi kabul eder.
let testEnv = await initializeTestEnvironment({ projectId: "demo-project-1234", firestore: { rules: fs.readFileSync("firestore.rules", "utf8"), }, });
RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext
Bu yöntem, kimliği doğrulanmış bir Kimlik Doğrulama kullanıcısı gibi davranan bir RulesTestContext
oluşturur. Döndürülen bağlam aracılığıyla oluşturulan isteklere sahte bir kimlik doğrulama jetonu eklenir. İsteğe bağlı olarak, Kimlik doğrulama jetonu yükleri için özel talepler veya geçersiz kılmalar tanımlayan bir nesne iletin.
initializeTestEnvironment
ile yapılandırılanlar da dahil olmak üzere yapılandırılmış herhangi bir emülatör örneklerine erişmek için testlerinizde döndürülen test bağlam nesnesini kullanın.
// Assuming a Firestore app and the Firestore emulator for this example import { setDoc } from "firebase/firestore"; const alice = testEnv.authenticatedContext("alice", { … }); // Use the Firestore instance associated with this context await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
RulesTestEnvironment.unauthenticatedContext() => RulesTestContext
Bu yöntem, Authentication aracılığıyla giriş yapılmamış bir istemci gibi davranan bir RulesTestContext
oluşturur. Döndürülen bağlam aracılığıyla oluşturulan isteklere Firebase Auth jetonları eklenmez.
initializeTestEnvironment
ile yapılandırılanlar da dahil olmak üzere yapılandırılmış herhangi bir emülatör örneklerine erişmek için testlerinizde döndürülen test bağlam nesnesini kullanın.
// Assuming a Cloud Storage app and the Storage emulator for this example import { getStorage, ref, deleteObject } from "firebase/storage"; const alice = testEnv.unauthenticatedContext(); // Use the Cloud Storage instance associated with this context const desertRef = ref(alice.storage(), 'images/desert.jpg'); await assertSucceeds(deleteObject(desertRef));
RulesTestEnvironment.withSecurityRulesDisabled()
Güvenlik Kuralları devre dışıymış gibi davranan bağlama sahip bir test kurulum işlevi çalıştırın.
Bu yöntem, Security-Rules-bypassing bağlamını alıp bir taahhüt döndüren bir geri çağırma işlevi alır. Vaat çözümlendiğinde / reddedildiğinde bağlam yok edilir.
RulesTestEnvironment.cleanup()
Bu yöntem, test ortamında oluşturulan tüm RulesTestContexts
öğelerini kaldırır ve temel kaynakları temizleyerek temiz bir çıkış sağlar.
Bu yöntem, emülatörlerin durumunu hiçbir şekilde değiştirmez. Testler arasında verileri sıfırlamak için uygulama emülatörüne özgü net veri yöntemini kullanın.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Bu, bir test durumu yardımcı işlevidir.
İşlev, sağlanan bir emülatör işlemini sarmalayan Promise'in hiçbir Güvenlik Kuralı ihlali olmadan çözümleneceğini iddia eder.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Bu, bir test durumu yardımcı işlevidir.
İşlev, sağlanan bir emülatör işlemini sarmalayan Promise'in Güvenlik Kuralları ihlali nedeniyle reddedileceğini iddia eder.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Emülatöre özel yöntemler
Ayrıca v9 SDK'sındaki yaygın test yöntemlerini ve yardımcı program işlevlerine de bakın.
RulesTestEnvironment.clearFirestore() => Promise<void>
Bu yöntem, Firestore veritabanındaki Firestore emülatörü için yapılandırılan projectId
öğesine ait verileri temizler.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Bu yöntem, bu test bağlamı için bir Firestore örneği alır. Döndürülen Firebase JS Client SDK örneği, istemci SDK API'leriyle (v9 modüler veya v9 uyumlu) kullanılabilir.
Kural değerlendirmelerini görselleştirme
Cloud Firestore emülatörü, Firebase Güvenlik Kuralları için değerlendirme izleme dahil olmak üzere istemci isteklerini Emulator Suite kullanıcı arayüzünde görselleştirmenizi sağlar.
Her isteğin ayrıntılı değerlendirme sırasını görüntülemek için Firestore > İstekler sekmesini açın.
Test raporları oluşturma
Bir dizi test çalıştırdıktan sonra, güvenlik kurallarınızın her birinin nasıl değerlendirildiğini gösteren test kapsamı raporlarına erişebilirsiniz.
Raporları almak için emülatör çalışırken açığa çıkan bir uç noktayı sorgulayın. Tarayıcı dostu bir sürüm için aşağıdaki URL'yi kullanın:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html
Bu işlem, kurallarınızı ifadelere ve alt ifadelere böler. Bunları, değerlendirme sayısı ve döndürülen değerlerin sayısı dahil olmak üzere daha fazla bilgi için fareyle üzerine gelebilirsiniz. Bu verilerin ham JSON sürümü için sorgunuza aşağıdaki URL'yi ekleyin:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage
Emülatör ile üretim arasındaki farklar
- Açıkça bir Cloud Firestore projesi oluşturmanız gerekmez. Emülatör, erişilen her örneği otomatik olarak oluşturur.
- Cloud Firestore emülatörü, normal Firebase Authentication akışıyla çalışmaz.
Bunun yerine, Firebase Test SDK'sında
rules-unit-testing
kitaplığındaauth
alanını alaninitializeTestApp()
yöntemini sağladık. Bu yöntem kullanılarak oluşturulan Firebase herkese açık kullanıcı adı, sağladığınız varlık kimliği başarıyla doğrulanmış gibi davranır.null
öğesini geçirirseniz kimliği doğrulanmamış kullanıcı olarak davranır (örneğin,auth != null
kuralları başarısız olur).
Bilinen sorunları giderme
Cloud Firestore emülatörünü kullanırken aşağıdaki bilinen sorunlarla karşılaşabilirsiniz. Karşılaştığınız düzensiz davranışlarla ilgili sorunları gidermek için aşağıdaki yönergeleri uygulayın. Bu notlar, Güvenlik Kuralları birimi test kitaplığı göz önünde bulundurularak yazılmış olsa da genel yaklaşımlar tüm Firebase SDK'ları için geçerlidir.
Test davranışı tutarsız
Testleriniz, testlerde herhangi bir değişiklik yapılmadan bile zaman zaman başarılı ve başarısız oluyorsa bunların doğru bir şekilde sıralandığını doğrulamanız gerekebilir.
Emülatörle kurulan etkileşimlerin çoğu eşzamansız olduğundan, tüm eşzamansız kodların doğru sıralandığından emin olun. Zincirleme vaatlerle veya await
notasyonunu serbest bir şekilde kullanarak sıralamayı düzeltebilirsiniz.
Özellikle aşağıdaki eşzamansız işlemleri gözden geçirin:
- Örneğin,
initializeTestEnvironment
ile güvenlik kuralları ayarlanıyor. - Veri okuma ve yazma (örneğin,
db.collection("users").doc("alice").get()
). assertSucceeds
veassertFails
dahil olmak üzere operasyonel onaylar.
Testler yalnızca emülatörü ilk kez yüklediğinizde başarılı olur
Emülatör durum bilgili. Kendisine yazılan tüm verileri bellekte depolar. Böylece emülatör her kapatıldığında tüm veriler kaybolur. Aynı proje kimliğiyle birden fazla test çalıştırıyorsanız her test, sonraki testleri etkileyebilecek veriler üretebilir. Bu davranışı önlemek için aşağıdaki yöntemlerden birini kullanabilirsiniz:
- Her test için benzersiz proje kimlikleri kullanın. Bunu yapmayı seçerseniz her testin parçası olarak
initializeTestEnvironment
öğesini çağırmanız gerekeceğini unutmayın. Kurallar yalnızca varsayılan proje kimliği için otomatik olarak yüklenir. - Testlerinizi, önceden yazılmış verilerle etkileşim kurmayacak şekilde yeniden yapılandırın (örneğin, her test için farklı bir koleksiyon kullanın).
- Test sırasında yazılan tüm verileri silin.
Test kurulumu çok karmaşık
Testinizi ayarlarken verileri Cloud Firestore Güvenlik Kurallarınızın gerçekten izin vermediği şekilde değiştirmek isteyebilirsiniz. Kurallarınız test kurulumunu karmaşık hale getiriyorsa kurulum adımlarında RulesTestEnvironment.withSecurityRulesDisabled
kullanmayı deneyin. Böylece okuma ve yazma işlemleri PERMISSION_DENIED
hatalarını tetiklemez.
Sonrasında testiniz, RulesTestEnvironment.authenticatedContext
ve unauthenticatedContext
kullanarak sırasıyla kimliği doğrulanmış veya kimliği doğrulanmamış kullanıcı olarak işlemler gerçekleştirebilir. Bu sayede, Cloud Firestore Güvenlik Kurallarınızın farklı durumlara doğru şekilde izin verdiğini veya bunları reddettiğini doğrulayabilirsiniz.