آلية عمل "قواعد الأمان"

يمكن أن يكون الأمان أحد أكثر العناصر تعقيدًا في عملية تطوير التطبيقات. في معظم التطبيقات، على المطوّرين إنشاء خادم وتشغيله لمعالجة المصادقة (تحديد هوية المستخدم) والتفويض (المهام التي يمكن للمستخدم تنفيذها).

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>>
  }
}

من المهم فهم المفاهيم الرئيسية التالية أثناء إنشاء القواعد:

  • الطلب: الطريقة أو الطرق التي تمّ استدعاؤها في بيان allow. هذه هي methods التي تسمح بتنفيذها. الطرق العادية هي: get وlist create وupdate وdelete. تتيح الطريقتان المختصرتان read وwrite قراءة البيانات وكتابتها على نطاق واسع في قاعدة البيانات أو مسار التخزين المحدَّد.
  • المسار: قاعدة البيانات أو مكان التخزين، يتم تمثيله على أنّه مسار ملف شخصي على الإنترنت.
  • القاعدة: عبارة allow التي تتضمّن شرطًا يسمح بتقديم طلب إذا تم تقييمه على أنّه صحيح.

الإصدار 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 عمليات كتابة وأنّ قواعد الأمان تستخدم طلبَي وصول إلى المستند للتحقّق من صحة كل عملية كتابة. في هذه الحالة، يستخدم كل إجراء كتابة طلبَي وصول من أصل 10 طلبات، ويستخدم طلب الكتابة المجمّعة 6 من طلبَي الوصول العشرين.

ويؤدي تجاوز أي من الحدّين إلى ظهور خطأ يفيد برفض الإذن.

قد يتم تخزين بعض طلبات الوصول إلى المستندات مؤقتًا، ولا يتم احتساب الطلبات المخزّنة مؤقتًا ضمن الحدود المسموح بها.

الحد الأقصى لعمق بيان match المُدمَج 10
الحد الأقصى المسموح به لطول المسار، في أقسام المسار، ضمن مجموعة من عبارات match المتداخلة 100
الحد الأقصى لعدد متغيّرات تسجيل المسارات المسموح بها ضمن مجموعة من عبارات match المتداخلة 20
الحد الأقصى لعمق استدعاء الدالة 20
الحد الأقصى لعدد وسيطات الدالة 7
الحد الأقصى لعدد عمليات ربط المتغيّرات let لكل دالة 10
الحد الأقصى لعدد عمليات استدعاء الدوالّ المتكررة أو الدورية 0 &lpar;غير مسموح به&rpar;
الحد الأقصى لعدد التعبيرات التي يتم تقييمها لكل طلب 1,000
الحد الأقصى لحجم مجموعة القواعد يجب أن تلتزم مجموعات القواعد بحدود حجمَين:
  • حدّ أقصى يبلغ 256 كيلوبايت لحجم مصدر نصّ قاعدة القواعد المنشور من وحدة تحكّم Firebase أو من سطر الأوامر باستخدام firebase deploy
  • حدّ أقصى يبلغ 250 كيلوبايت لحجم مجموعة القواعد المجمّعة التي تنتج عندما تعالج 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>>
  }
}

من المهم فهم المفاهيم الرئيسية التالية أثناء إنشاء القواعد:

  • الطلب: الطريقة أو الطرق التي تمّ استدعاؤها في بيان allow. هذه هي methods التي تسمح بتنفيذها. الطرق العادية هي: get وlist create وupdate وdelete. تتيح الطريقتان المختصرتان read وwrite قراءة البيانات وكتابتها على نطاق واسع في قاعدة البيانات أو مسار التخزين المحدَّد.
  • المسار: قاعدة البيانات أو مكان التخزين، يتم تمثيله على أنّه مسار ملف شخصي على الإنترنت.
  • القاعدة: عبارة allow التي تتضمّن شرطًا يسمح بتقديم طلب إذا تم تقييمه على أنّه صحيح.

مسارات المطابقة

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 صحيحة، في حين يخضع الملف "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 أيضًا على المعرّف الفريد للمستخدم وحمله Firebase Authentication في عنصر request.auth، وسيتم توضيح ذلك بمزيد من التفصيل في قسم المصادقة في المستندات.

في ما يلي قائمة كاملة بالسمات في عنصر request:

الموقع النوع الوصف
auth map<string, string> عندما يكون المستخدم مسجِّلاً الدخول، يقدّم uid، وهو المعرّف الفريد للمستخدم، token، وهو خريطة لمطالبات Firebase Authentication JWT. بخلاف ذلك، سيكون null.
params map<string, string> خريطة تحتوي على مَعلمات طلب البحث
path المسار path يمثّل المسار الذي يتم تنفيذ الطلب عليه
resource map<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 map<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 كعملية إثبات ملكية ثانوية لمنح إذن الوصول استنادًا إلى بيانات واردة أو حالية.
  • الشرط: الشرط الذي يسمح بطلب إذا تم تقييمه على أنّه صحيح.

كيفية تطبيق القواعد على المسارات

في 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
})
جافا
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!
})
جافا
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 }
      }
    }
  }