איך פועלים כללי האבטחה

אבטחה יכולה להיות אחד מהחלקים המורכבים ביותר בפאזלים של פיתוח אפליקציה. במרבית האפליקציות, המפתחים צריכים ליצור ולהפעיל שרת מטפל באימות (מי המשתמש) ובהרשאה (מה משתמש יכול לעשות).

Firebase Security Rules מסירים את השכבה האמצעית (שרת) ומאפשרים לציין מבוסס-נתיב הרשאות ללקוחות שמתחברים ישירות לנתונים שלכם. במדריך הזה מוסבר איך הכללים חלים על בקשות נכנסות.

יש לבחור מוצר כדי לקבל מידע נוסף על הכללים שלו.

Cloud Firestore

מבנה בסיסי

Firebase Security Rules ב-Cloud Firestore וב-Cloud Storage משתמשים במבנה הבא ו תחביר:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

חשוב להבין את מושגי המפתח הבאים בזמן שאתם מגדירים את הכללים:

  • Request: השיטות שהופעלו בהצהרה allow. הנושאים האלה שיטות שאתם מאפשרים להפעיל. השיטות הרגילות הן: get, list, create, update וגם delete. שיטות הנוחות read וwrite להפעיל גישת קריאה וכתיבה רחבה במסד הנתונים או בנתיב האחסון שצוינו.
  • נתיב: המיקום של מסד הנתונים או האחסון, מיוצג בתור נתיב URI.
  • הכלל: ההצהרה allow, שכוללת תנאי שמאפשר אם הערך הוא True.

כללי אבטחה בגרסה 2

החל ממאי 2019, גרסה 2 של כללי האבטחה Firebase זמינה עכשיו זמינים. גרסה 2 של הכללים משנה את ההתנהגות של רקורסיביות תווים כלליים לחיפוש {name=**}. חייבים להשתמש בגרסה 2 אם אתם מתכננים לעשות להשתמש בשאילתות על קבוצות אוספים. עליכם להביע הסכמה אל גרסה 2 על ידי הפיכת rules_version = '2'; לשורה הראשונה באבטחה כללים:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

נתיבים תואמים

כל הצהרות ההתאמה צריכות להפנות למסמכים, ולא לאוספים. התאמה ההצהרה יכולה להפנות למסמך ספציפי, כמו match /cities/SF, או להשתמש בתווים כלליים לחיפוש כדי להצביע על מסמך כלשהו בנתיב שצוין, כמו ב-match /cities/{city}.

בדוגמה שלמעלה, משפט ההתאמה משתמש בתחביר התו הכללי {city}. המשמעות היא שהכלל חל על כל מסמך באוסף cities, כמו /cities/SF או /cities/NYC. כשהביטויים allow בהצהרת ההתאמה הם מוערך, המשתנה city יקבל את שם המסמך של העיר, כמו SF או NYC.

אוספי משנה תואמים

הנתונים ב-Cloud Firestore מאורגנים באוספים של מסמכים, וכל אחד מהם יכול להרחיב את ההיררכיה באמצעות אוספי משנה. חשוב להבין את האינטראקציה של כללי אבטחה עם נתונים היררכיים.

נניח שכל מסמך באוסף 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 וגם באוספי המשנה.

תווים כלליים לחיפוש רקורסיבי חייבים להופיע בסוף הצהרת התאמה.

גרסה 2

בגרסה 2 של כללי האבטחה, תווים כלליים לחיפוש רקורסיביים תואמים לאפס נתיב או יותר פריטים. match/cities/{city}/{document=**} תואם למסמכים בכל ואוספים נוספים וכן מסמכים באוסף cities.

צריך להצטרף לגרסה 2. לשם כך, מוסיפים את 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 חלה גם על כל אחד מהם פעולה.

    לדוגמה, נניח שאתם יוצרים בקשת כתיבה באצווה עם 3 פעולות כתיבה ושכללי האבטחה שלך משתמשים ב-2 מסמכים גישה לקריאות לאימות כל כתיבה. במקרה הזה, כל כתיבה משתמשת 2 מתוך 10 קריאות הגישה שלו ובקשת הכתיבה באצווה משתמשת ב-6 ל-20 שיחות גישה.

אם חורגים מכל אחת מהמגבלות האלה, מתקבלת הודעת שגיאה מסוג 'הרשאה נדחתה'.

ייתכן שחלק מהקריאות לגישה למסמכים יישמרו במטמון, ושיחות שנשמרו במטמון לא נכללות בחישוב של המגבלות.

עומק הקינון המקסימלי של משפטי match 10
אורך נתיב מקסימלי, במקטעי נתיב, מותר בתוך קבוצה של match דוחות 100
מספר מקסימלי של משתני לכידת נתיב שמותר בקבוצה של דפי match בתצוגת עץ 20
עומק הקריאה המקסימלי של פונקציה 20
המספר המקסימלי של ארגומנטים של פונקציות 7
המספר המקסימלי של קישורי משתני let לכל פונקציה 10
המספר המקסימלי של הפעלות של פונקציות רקורסיביות או מחזוריות 0 &lpar;לא אפשרי&rpar;
המספר המקסימלי של ביטויים שנבדקים לכל בקשה 1,000
גודל מקסימלי של קבוצת כללים קבוצות הכללים חייבות לעמוד בשני מגבלות גודל:
  • מגבלה של 256KB על הגודל של מקור הטקסט בקבוצת הכללים שפורסמו ממסוף Firebase או מ-CLI באמצעות firebase deploy.
  • מגבלה של 250KB על גודל קבוצת הכללים המתומצתת שנוצרת כש-Firebase מעבד את המקור ועושה אותו פעיל בקצה העורפי.

Cloud Storage

המבנה הבסיסי

Firebase Security Rules ב-Cloud Firestore וב-Cloud Storage משתמשים במבנה הבא ו תחביר:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

חשוב להבין את מושגי המפתח הבאים בזמן שאתם מגדירים את הכללים:

  • Request: השיטות שהופעלו בהצהרה allow. הנושאים האלה שיטות שאתם מאפשרים להפעיל. השיטות הרגילות הן: get, list, create, update וגם delete. שיטות הנוחות read וwrite להפעיל גישת קריאה וכתיבה רחבה במסד הנתונים או בנתיב האחסון שצוינו.
  • נתיב: המיקום של מסד הנתונים או האחסון, מיוצג בתור נתיב URI.
  • הכלל: ההצהרה allow, שכוללת תנאי שמאפשר אם הערך הוא True.

נתיבים תואמים

Cloud Storage Security Rules match נתיבי הקבצים שמשמשים לגישה לקבצים ב-Cloud Storage. כללים יכולים match נתיבים מדויקים או נתיבים עם תווים כלליים לחיפוש, וגם אפשר גם להציב כללים בתצוגת עץ. אם אין כלל התאמה שמאפשר שיטת בקשה, או אם התנאי מקבל את הערך false, הבקשה נדחית.

התאמות מדויקות

// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
  allow write: if <condition>;
}

// Exact match for "images/croppedProfilePhoto.png"
match /images/croppedProfilePhoto.png {
  allow write: if <other_condition>;
}

התאמות מקננות

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/profilePhoto.png"
  match /profilePhoto.png {
    allow write: if <condition>;
  }

  // Exact match for "images/croppedProfilePhoto.png"
  match /croppedProfilePhoto.png {
    allow write: if <other_condition>;
  }
}

התאמות של תווים כלליים לחיפוש

אפשר להשתמש בכללים גם כדי match דפוס באמצעות תווים כלליים לחיפוש. תו כללי לחיפוש הוא משתנה בעל שם שמייצג מחרוזת יחידה, profilePhoto.png, או כמה מקטעי נתיב, כמו images/profilePhoto.png.

כדי ליצור תו כללי לחיפוש, מוסיפים סוגריים מסולסלים מסביב לשם של התו הכללי לחיפוש, כמו {string} כדי להצהיר על תו כללי לחיפוש עם כמה פלחים, מוסיפים את הערך =** לשם של התו הכללי לחיפוש, כמו {path=**}:

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/*"
  // e.g. images/profilePhoto.png is matched
  match /{imageId} {
    // This rule only matches a single path segment (*)
    // imageId is a string that contains the specific segment matched
    allow read: if <condition>;
  }

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

אם יש מספר כללים שתואמים לקובץ מסוים, התוצאה היא OR של התוצאה של כל הקובץ הערכות של כללים. כלומר, אם כלל כלשהו שתואם לקובץ מקבל ערך true, הערך של הפרמטר התוצאה היא true.

בכללים שלמעלה, הקובץ "images/profilePhoto.png" ניתן לקרוא אם אחד מהם הערך של condition או other_condition הוא True, אבל הקובץ "images/users/user:12345/profilePhoto.png" כפוף לתוצאה של other_condition.

אפשר להפנות למשתנה תו כללי לחיפוש מתוך ההרשאה של שם הקובץ או הנתיב של הספק match:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Cloud Storage Security Rules לא מדורגים, והכללים נבדקים רק כאשר נתיב הבקשה תואם לנתיב שצוינו בכללים.

בקשת הערכה

העלאות, הורדות, שינויים במטא-נתונים ומחיקות מוערכות באמצעות נשלח סכום של request אל Cloud Storage. המשתנה request מכיל את נתיב הקובץ שבו מתבצעת הבקשה, את השעה שבה התקבלה הבקשה ואת הערך החדש של resource אם הבקשה היא לכתיבה. גם כותרות HTTP ומצב האימות נכללים.

האובייקט request מכיל גם את המזהה הייחודי של המשתמש וגם את המטען הייעודי (payload) מסוג Firebase Authentication באובייקט request.auth, שיהיה שמוסברים בפירוט בקטע אימות של המסמכים.

רשימה מלאה של המאפיינים באובייקט request זמינה בהמשך:

נכס סוג תיאור
auth map<string, string> כשמשתמש מחובר, מספק uid, המזהה הייחודי של המשתמש, וגם token, מפה של Firebase Authentication הצהרות JWT. אחרת, null
params map<string, string> מפה שמכילה את הפרמטרים של השאילתה של הבקשה.
path נתיב path שמייצג את הנתיב שבו הבקשה נמצאת הביצועים של.
resource מפה<string, string> ערך המשאב החדש, שמופיע רק בבקשות write.
time חותמת זמן חותמת זמן שמייצגת את הזמן שבו מתבצעת בדיקת הבקשה בשרת.

הערכת משאבים

כשבוחנים כללים, מומלץ גם להעריך את המטא-נתונים של הקובץ העלאות, הורדה, שינוי או מחיקה. כך אפשר ליצור הם כללים מורכבים וחזקים שעושים דברים כמו לאפשר רק קבצים עם מאפיינים מסוימים סוגי תוכן להעלאה, או רק קבצים שגדולים מגודל מסוים נמחק.

Firebase Security Rules עבור Cloud Storage מספק מטא-נתונים של קבצים בresource שמכיל צמדי מפתח/ערך של המטא-נתונים שמופיעים אובייקט Cloud Storage. אפשר לבדוק את המאפיינים האלה בבקשות read או write כדי לוודא את תקינות הנתונים.

בבקשות write (כמו העלאות, עדכוני מטא-נתונים ומחיקות), ב- בנוסף לאובייקט resource, שמכיל מטא-נתונים של הקובץ שקיים כרגע בנתיב הבקשה, אפשר גם להשתמש אובייקט request.resource, שמכיל קבוצת משנה של המטא-נתונים של הקובץ כתיבה, אם הכתיבה מותרת. אפשר להשתמש בשני הערכים האלה כדי להבטיח תקינות או אכיפת מגבלות של אפליקציה כגון סוג או גודל הקובץ.

רשימה מלאה של המאפיינים באובייקט resource זמינה בהמשך:

נכס סוג תיאור
name מחרוזת השם המלא של האובייקט
bucket מחרוזת שם הקטגוריה שבה נמצא האובייקט הזה.
generation int Google Cloud Storage של האובייקט הזה.
metageneration int Google Cloud Storage את המטא-גנרציה של האובייקט.
size int גודל האובייקט בבייטים.
timeCreated חותמת זמן חותמת זמן שמייצגת את השעה שבה האובייקט נוצר.
updated חותמת זמן חותמת זמן שמייצגת את הזמן שבו אובייקט עודכן לאחרונה.
md5Hash מחרוזת גיבוב MD5 של האובייקט.
crc32c מחרוזת גיבוב CRC32C של האובייקט.
etag מחרוזת ה-ETag שמשויך לאובייקט הזה.
contentDisposition מחרוזת צורת התוכן שמשויכת לאובייקט הזה.
contentEncoding מחרוזת קידוד התוכן שמשויך לאובייקט הזה.
contentLanguage מחרוזת שפת התוכן שמשויכת לאובייקט הזה.
contentType מחרוזת סוג התוכן שמשויך לאובייקט הזה.
metadata מפה<string, string> צמדי מפתח/ערך של מטא-נתונים מותאמים אישית נוספים שצוינו על ידי המפתח.

השדה request.resource מכיל את כל הערכים האלה, מלבד generation,‏ metageneration,‏ etag,‏ timeCreated ו-updated.

מגבלות על כללי אבטחה

כשאתם עובדים עם כללי אבטחה, שימו לב למגבלות הבאות:

הגבלה פרטים
המספר המקסימלי של קריאות firestore.exists() ו-firestore.get() לכל בקשה

2 לבקשות למסמך יחיד ובקשות שאילתה.

חריגה מהמגבלה תגרום לשגיאה של דחיית ההרשאה.

גישה לקריאות לאותם מסמכים עשויה להישמר במטמון ולשיחות שנשמרו במטמון לא נספרים כחלק מהמגבלות.

דוגמה מלאה

כשמשלבים את כל המידע הזה יחד, אפשר ליצור דוגמה מלאה לכללים עבור תמונה פתרון אחסון:

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Realtime Database

מבנה בסיסי

ב-Realtime Database, Firebase Security Rules מכיל ביטויים דמויי JavaScript שנכללים בתוך רכיב מסמך JSON.

נעשה בהם שימוש בתחביר הבא:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

הכלל כולל שלושה רכיבים בסיסיים:

  • נתיב: המיקום של מסד הנתונים. הנתונים האלה מראים את מבנה ה-JSON של מסד הנתונים.
  • בקשה: אלה השיטות שבהן הכלל משתמש כדי להעניק גישה. read ו-write כללים מעניקים גישת קריאה וכתיבה רחבה, ואילו validate כללים לשמש כאימות משני להענקת גישה על סמך נתונים נכנסים או קיימים .
  • תנאי: התנאי שמאפשר בקשה אם היא מקבלת את הערך True.

איך כללים חלים על נתיבים

ב-Realtime Database, Rules חלה באופן אטומי, כלומר כללים בצמתים הורים ברמה גבוהה יותר מבטלים כללים בצמתים צאצאים ברמה מפורטת יותר, וכללים בצומת עמוק יותר לא יכולים להעניק גישה לנתיב הורה. שלך לא יכול לצמצם או לבטל את הגישה בנתיב עמוק יותר במבנה מסד הנתונים כבר הענקתם אותו עבור אחד מנתיבי ההורה.

חשוב להביא בחשבון את הכללים הבאים:

{
  "rules": {
     "foo": {
        // allows read to /foo/*
        ".read": "data.child('baz').val() === true",
        "bar": {
          // ignored, since read was allowed already
          ".read": false
        }
     }
  }
}

מבנה האבטחה הזה מאפשר לקרוא את /bar/ בכל פעם המאפיין /foo/ מכיל צאצא baz עם הערך true. בכלל ".read": false תחת /foo/bar/ לא כאן, מכיוון שנתיב צאצא לא יכול לבטל את הגישה.

יכול להיות שהתכונה הזו לא תראה אינטואיטיבית במבט ראשון, אבל היא חלק חזק בשפת הכללים ומאפשרת להטמיע הרשאות גישה מורכבות מאוד במאמץ מינימלי. האפשרות הזו שימושית במיוחד לאבטחה מבוססת-משתמשים.

עם זאת, כללי .validate לא מדורגים לפי דרגה. כל כללי האימות צריך לעמוד בכל הרמות בהיררכיה כדי שפעולת הכתיבה תאושר.

בנוסף, מאחר שכללים לא חלים על נתיב הורה, או על קריאה או כתיבה הפעולה תיכשל אם אין כלל במיקום המבוקש או אצל הורה מיקום שמעניק גישה. גם אם יש גישה לכל נתיב הצאצא שמושפע, הקריאה במיקום ההורה תיכשל לחלוטין. חשוב על המבנה הזה:

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

בלי להבין שכללים נבדקים באופן אטומי, למשל, אחזור הנתיב /records/ יחזיר rec1 אבל לא rec2. עם זאת, התוצאה בפועל היא שגיאה:

JavaScript
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
Objective-C
הערה: מוצר Firebase הזה לא זמין ביעד 'קליפ של אפליקציה'.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
  // success block is not called
} withCancelBlock:^(NSError * _Nonnull error) {
  // cancel block triggered with PERMISSION_DENIED
}];
Swift
הערה: מוצר Firebase הזה לא זמין ביעד של קטע מקדים לאפליקציה.
var ref = FIRDatabase.database().reference()
ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // success block is not called
}, withCancelBlock: { error in
    // cancel block triggered with PERMISSION_DENIED
})
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // success method is not called
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback triggered with PERMISSION_DENIED
  });
});
REST
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

פעולת הקריאה ב-/records/ היא אטומית, ואין כלל קריאה שמעניק גישה לכל הנתונים במסגרת /records/, ולכן תתקבל השגיאה PERMISSION_DENIED. אם נבדוק את הכלל בסימולטור האבטחה במסוף Firebase, נוכל לראות שפעולת הקריאה נדחתה:

Attempt to read /records with auth=Success(null)
    /
    /records

No .read rule allowed the operation.
Read was denied.

הפעולה נדחתה כי אף כלל קריאה לא אישר גישה לנתיב /records/, אבל חשוב לשים לב שהכלל של rec1 אף פעם לא בוצעה הערכה כי הוא לא היה בנתיב שביקשנו. כדי לאחזר את rec1, נצטרך לגשת אליו ישירות:

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
הערה: מוצר Firebase הזה לא זמין ביעד 'קליפ של אפליקציה'.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Swift
הערה: מוצר Firebase הזה לא זמין ביעד של קטע מקדים לאפליקציה.
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records/rec1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // SUCCESS!
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback is not called
  }
});
REST
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

משתנה מיקום

Realtime Database Rules תומך ב-$location כדי להתאים לפלחי הנתיב. צריך להוסיף את הקידומת $ לפני הנתיב פלח כדי להתאים את הכלל שלך לכל צומתי צאצא לאורך הנתיב.

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

אפשר גם להשתמש ב-$variable במקביל לשמות נתיב קבועים.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }