Firebase Security Rules מאפשרים לכם לשלוט בגישה לנתונים שמאוחסנים. התחביר הגמיש של הכללים מאפשר ליצור כללים שמתאימים לכל דבר, החל מכל פעולות הכתיבה במסד הנתונים כולו ועד לפעולות במסמך ספציפי.
במדריך הזה מתוארים כמה מהתרחישים לדוגמה הבסיסיים יותר שאולי תרצו להטמיע בזמן הגדרת האפליקציה וההגנה על הנתונים. אבל לפני שמתחילים לכתוב כללים, כדאי ללמוד עוד על השפה שבה הם כתובים ועל ההתנהגות שלהם.
כדי לגשת לכללים ולעדכן אותם, פועלים לפי השלבים שמפורטים במאמר ניהול ופריסה של Firebase Security Rules.
הנחיית AI לכלים מבוססי-AI
כדי לקבל עזרה מ-AI, מעתיקים את ההנחיה שלמטה אל סוכן ה-AI לתכנות (כמו 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 data.
כללי ברירת המחדל: מצב נעילה
כשיוצרים מסד נתונים או מכונה של אחסון במסוף Firebase, בוחרים אם Firebase Security Rules יגבילו את הגישה לנתונים (מצב נעילה) או יאפשרו לכל אחד לגשת אליהם (מצב בדיקה). ב-Cloud Firestore וב-Realtime Database, כללי ברירת המחדל של מצב נעילה חוסמים את הגישה לכל המשתמשים. ב-Cloud Storage, רק משתמשים מאומתים יכולים לגשת לקטגוריות האחסון.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
כללים של סביבת פיתוח
בזמן שאתם עובדים על האפליקציה, יכול להיות שתרצו גישה פתוחה או בלתי מוגבלת יחסית לנתונים. רק חשוב לעדכן את Security Rules לפני שפורסים את האפליקציה בסביבת הייצור. חשוב גם לזכור שאם פורסים את האפליקציה, היא נגישה לכולם – גם אם לא משיקים אותה.
חשוב לזכור ש-Firebase מאפשרת ללקוחות גישה ישירה לנתונים, וFirebase Security Rules הם אמצעי ההגנה היחיד שחוסם גישה של משתמשים זדוניים. להגדרת כללים בנפרד מהלוגיקה של המוצר יש כמה יתרונות: הלקוחות לא אחראים לאכיפת האבטחה, הטמעות עם באגים לא יסכנו את הנתונים שלכם, והכי חשוב – אתם לא מסתמכים על שרת מתווך כדי להגן על הנתונים מפני העולם.
כל המשתמשים המאומתים
אנחנו לא ממליצים להשאיר את הנתונים נגישים לכל משתמש שמחובר, אבל יכול להיות שיהיה שימושי להגדיר גישה לכל משתמש מאומת בזמן פיתוח האפליקציה.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /some_collection/{document} {
allow read, write: if request.auth != null;
}
}
}
Realtime Database
{
"rules": {
"some_path": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /some_folder/{fileName} {
allow read, write: if request.auth != null;
}
}
}
כללים שמוכנים לייצור
כשאתם מתכוננים לפרוס את האפליקציה, חשוב לוודא שהנתונים מוגנים ושהמשתמשים מקבלים גישה כמו שצריך. כדי להגדיר גישה מבוססת-משתמש, משתמשים ב-Authentication, וכדי להגדיר גישה מבוססת-נתונים, קוראים ישירות ממסד הנתונים.
כדאי לכתוב כללים כשאתם מגדירים את מבנה הנתונים, כי האופן שבו אתם מגדירים את הכללים משפיע על הדרך שבה אתם מגבילים את הגישה לנתונים בנתיבים שונים.
גישה לבעלי התוכן בלבד
הכללים האלה מגבילים את הגישה לבעלים המאומתים של התוכן בלבד. רק משתמש אחד יכול לקרוא את הנתונים ולכתוב אותם, ונתיב הנתונים מכיל את מזהה המשתמש.
מתי הכלל הזה עובד: הכלל הזה עובד טוב אם הנתונים מופרדים לפי משתמש – אם המשתמש היחיד שצריך לגשת לנתונים הוא אותו משתמש שיצר את הנתונים.
מתי הכלל הזה לא עובד: קבוצת הכללים הזו לא עובדת כשכמה משתמשים צריכים לכתוב או לקרוא את אותם נתונים – המשתמשים יחליפו נתונים או לא יוכלו לגשת לנתונים שהם יצרו.
כדי להגדיר את הכלל הזה: יוצרים כלל שמאשר שהמשתמש שמבקש גישה לקריאה או לכתיבה של נתונים הוא המשתמש שבבעלותו הנתונים האלה.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{document} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Cloud Storage
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/file.txt"
match /user/{userId}/{fileName} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
גישה מעורבת – ציבורית ופרטית
הכלל הזה מאפשר לכל אחד לקרוא מערך נתונים, אבל מגביל את היכולת ליצור או לשנות נתונים בנתיב נתון לבעלי התוכן המאומתים בלבד.
מתי הכלל הזה פועל: הכלל הזה פועל היטב באפליקציות שדורשות רכיבים שניתנים לקריאה באופן ציבורי, אבל צריך להגביל את הגישה לעריכה לבעלים של הרכיבים האלה. לדוגמה, אפליקציית צ'אט או בלוג.
מתי הכלל הזה לא עובד: כמו הכלל "בעלי התוכן בלבד", קבוצת הכללים הזו לא עובדת כשכמה משתמשים צריכים לערוך את אותם נתונים. בסופו של דבר, המשתמשים יחליפו את הנתונים אחד של השני.
כדי להגדיר את הכלל הזה: יוצרים כלל שמאפשר גישת קריאה לכל המשתמשים (או לכל המשתמשים המאומתים), ומאשר שהמשתמש שכותב נתונים הוא הבעלים.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
// Allow public reads
allow read: if true
// Allow creation if the current user owns the new document
allow create: if request.auth.uid == request.resource.data.author_uid;
// Allow updates by the owner, and prevent change of ownership
allow update: if request.auth.uid == request.resource.data.author_uid
&& request.auth.uid == resource.data.author_uid;
// Allow deletion if the current user owns the existing document
allow delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Realtime Database
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/file.txt"
match /user/{userId}/{fileName} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
גישה מבוססת-מאפיינים וגישה מבוססת-תפקידים
כדי שהכלל הזה יפעל, צריך להגדיר מאפיינים ולהקצות אותם למשתמשים בנתונים. Firebase Security Rules בודק את הבקשה מול הנתונים ממסד הנתונים או המטא-נתונים של הקובץ כדי לאשר או לדחות את הגישה.
מתי הכלל הזה פועל: אם אתם מקצים תפקיד למשתמשים, הכלל הזה מאפשר לכם להגביל את הגישה על סמך תפקידים או קבוצות ספציפיות של משתמשים. לדוגמה, אם אתם מאחסנים ציונים, אתם יכולים להקצות רמות גישה שונות לקבוצת "תלמידים" (קריאת התוכן שלהם בלבד), לקבוצת "מורים" (קריאה וכתיבה בנושא שלהם) ולקבוצת "מנהלים" (קריאת כל התוכן).
מתי הכלל הזה לא פועל: ב-Realtime Database וב-Cloud Storage, הכללים לא יכולים להשתמש בשיטה get() שאפשר לשלב בכללים של Cloud Firestore.
לכן, צריך לבנות את המטא-נתונים של מסד הנתונים או הקובץ כך שישקפו את המאפיינים שבהם אתם משתמשים בכללים.
כדי להגדיר את הכלל הזה: ב-Cloud Firestore, מוסיפים למסמכים של המשתמשים שדה שאתם יכולים לקרוא, ואז מגדירים את הכלל כך שיקרא את השדה הזה ויעניק גישה בהתאם לתנאי. ב-Realtime Database, יוצרים נתיב נתונים שמגדיר את המשתמשים באפליקציה ומקצה להם תפקיד בצומת צאצא.
אפשר גם להגדיר הצהרות מותאמות אישית ב-Authentication, ואז לאחזר את המידע הזה מהמשתנה auth.token בכל Firebase Security Rules.
מאפיינים ותפקידים שמוגדרים לפי נתונים
הכללים האלה פועלים רק ב-Cloud Firestore וב-Realtime Database.
Cloud Firestore
חשוב לזכור שבכל פעם שהכללים כוללים קריאה, כמו הכללים שבהמשך, אתם מחויבים על פעולת קריאה ב-Cloud Firestore.
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
מאפיינים ותפקידים של הצהרות בהתאמה אישית
כדי להטמיע את הכללים האלה, מגדירים הצהרות בהתאמה אישית ב-Firebase Authentication ואז משתמשים בהצהרות בכללים.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an administrator claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to use
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
Cloud Storage
service firebase.storage {
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
}
מאפייני שכירות
כדי להטמיע את הכללים האלה, מגדירים ריבוי דיירים (multitenancy) ב-Google Cloud Identity Platform (GCIP) ואז משתמשים בדייר בכללים. בדוגמאות הבאות, משתמש בדייר ספציפי, למשל tenant2-m6tyz, יכול לכתוב:
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
Cloud Storage
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}