قواعد أمان Firebase لمرجع التخزين السحابي

تُستخدم قواعد أمان Firebase للتخزين السحابي لتحديد من لديه حق الوصول للقراءة والكتابة إلى الملفات المخزنة في Cloud Storage، بالإضافة إلى كيفية تنظيم الملفات والبيانات الوصفية التي تحتوي عليها. تتكون قواعد أمان التخزين السحابي من قواعد تأخذ في الاعتبار request resource للسماح بالإجراء المطلوب أو رفضه، مثل تحميل ملف أو استرداد البيانات التعريفية للملف. تغطي هذه المستندات المرجعية أنواع القواعد، وخصائص request resource ، وأنواع البيانات المستخدمة بواسطة قواعد أمان التخزين السحابي، وكيفية حدوث الأخطاء.

قاعدة

rule هي تعبير يتم تقييمه لتحديد ما إذا كان request مسموحًا له بتنفيذ الإجراء المطلوب.

أنواع

يسمح

تتكون قواعد allow من طريقة، مثل read أو write ، بالإضافة إلى شرط اختياري. عند تنفيذ قاعدة، يتم تقييم الشرط، وإذا تم تقييم الشرط إلى true ، فسيتم السماح بالطريقة المطلوبة؛ وإلا، فسيتم رفض الأسلوب. allow قاعدة السماح بدون شرط دائمًا بالطريقة المطلوبة.

// Always allow method
allow <method>;

// Allow method if condition is true
allow <method>: if <condition>;

حاليًا، allow هو نوع القاعدة الوحيد المعتمد.

طرق الطلب

يقرأ

تغطي طريقة read جميع الطلبات التي تتم فيها قراءة بيانات الملف أو البيانات التعريفية، بما في ذلك تنزيلات الملفات وقراءة البيانات التعريفية للملف.

// Always allow reads
allow read;

// Allow reads if condition evaluates to true
allow read: if <condition>;

يكتب

تغطي طريقة write جميع الطلبات التي يتم فيها كتابة بيانات الملف أو البيانات التعريفية، بما في ذلك تحميل الملفات وحذف الملفات وتحديثات البيانات التعريفية للملف.

// Always allow writes
allow write;

// Allow writes if condition evaluates to true
allow write: if <condition>;

مباراة

يتم تنفيذ القواعد عندما يتطابق request المستخدم (مثل تحميل ملف أو تنزيله) مع مسار ملف تغطيه القاعدة. تتكون match من مسار ونص، ويجب أن يحتويا على قاعدة allow واحدة على الأقل. إذا لم يتم مطابقة أي مسار، فسيتم رفض الطلب.

يمكنك match مسار مسمى بالكامل، أو يمكنك إدراج أحرف بدل لمطابقة جميع المسارات التي تناسب نمطًا معينًا.

قطاعات المسار

single_segment

يمكنك استخدام مقاطع مسار واحدة لإنشاء قاعدة تتطابق مع ملف مخزن في Cloud Storage.

// Allow read at "path" if condition evaluates to true
match /path {
  allow read: if <condition>;
}

يُسمح أيضًا بمقاطع المسار المتعددة والمسارات المتداخلة:

// Allow read at "path/to/object" if condition evaluates to true
match /path {
  match /to {
    match /object {
      allow read: if <condition>;
    }
  }
}

{single_segment_wildcard}

إذا كنت تريد تطبيق قاعدة على ملفات متعددة في نفس المسار، فيمكنك استخدام مقطع مسار بدل لمطابقة جميع الملفات في مسار معين. يتم الإعلان عن متغير بدل في المسار عن طريق تغليف متغير بين قوسين متعرجين: {variable} . يمكن الوصول إلى هذا المتغير ضمن عبارة المطابقة string .

// Allow read at any path "/*", if condition evaluates to true
match /{single_path} {
  // Matches "path", "to", or "object" but not "path/to/object"
  allow read: if <condition>;
}

قد تحتوي أيضًا مقاطع المسار المتعددة والمسارات المتداخلة على أحرف بدل:

// Allow read at any path "/path/*/newPath/*", if condition evaluates to true
match /path/{first_wildcard} {
  match /newPath/{second_wildcard} {
    // Matches "path/to/newPath/newObject" or "path/from/newPath/oldObject"
    allow read: if <condition>;
  }
}

{multi_segment_wildcard=**}

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

يتم تعريف مسار حرف البدل متعدد المقاطع بشكل مشابه لحرف بدل مقطع واحد، مع إضافة =** في نهاية المتغير: {variable=**} . يتوفر متغير بدل متعدد المقاطع ضمن عبارة المطابقة ككائن path .

// Allow read at any path "/**", if condition evaluates to true
match /{multi_path=**} {
  // Matches anything at or below this, from "path", "path/to", "path/to/object", ...
  allow read: if <condition>;
}

طلب

يتم توفير متغير request ضمن شرط لتمثيل الطلب الذي يتم تقديمه في هذا المسار. يحتوي متغير request على عدد من الخصائص التي يمكن استخدامها لتحديد ما إذا كان سيتم السماح بالطلب الوارد أم لا.

ملكيات

auth

عندما يقوم مستخدم تمت مصادقته بتنفيذ طلب مقابل Cloud Storage، يتم ملء متغير auth بالمعرف uid الخاص بالمستخدم ( request.auth.uid ) بالإضافة إلى مطالبات Firebase Authentication JWT ( request.auth.token ).

يحتوي request.auth.token على بعض أو كل المفاتيح التالية:

مجال وصف
email عنوان البريد الإلكتروني المرتبط بالحساب، إن وجد.
email_verified true إذا كان المستخدم قد تحقق من أن لديه حق الوصول إلى عنوان email . يتحقق بعض مقدمي الخدمات تلقائيًا من عناوين البريد الإلكتروني التي يمتلكونها.
phone_number رقم الهاتف المرتبط بالحساب إن وجد.
name اسم العرض الخاص بالمستخدم، إذا تم تعيينه.
sub معرف Firebase UID الخاص بالمستخدم. هذا فريد من نوعه داخل المشروع.
firebase.identities قاموس لجميع الهويات المرتبطة بحساب هذا المستخدم. يمكن أن تكون مفاتيح القاموس أيًا مما يلي: email ، phone ، google.com ، facebook.com ، github.com ، twitter.com . قيم القاموس عبارة عن صفائف من المعرفات الفريدة لكل موفر هوية مرتبط بالحساب. على سبيل المثال، يحتوي auth.token.firebase.identities["google.com"][0] على أول معرف مستخدم Google مرتبط بالحساب.
firebase.sign_in_provider موفر تسجيل الدخول المستخدم للحصول على هذا الرمز المميز. يمكن أن تكون إحدى السلاسل التالية: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com .
firebase.tenant معرف المستأجر المرتبط بالحساب، إذا كان موجودًا. على سبيل المثال، tenant2-m6tyz

في حالة استخدام المصادقة المخصصة، يحتوي request.auth.token أيضًا على أي مطالبات مخصصة يحددها المطور.

عندما يقوم مستخدم غير مصادق بتنفيذ طلب، تكون request.auth null .

// Allow requests from authenticated users
allow read, write: if request.auth != null;

path

يحتوي متغير path على المسار الذي يتم تنفيذ request عليه.

// Allow a request if the first path segment equals "images"
allow read, write: if request.path[0] == 'images';

resource

يحتوي متغير resource على البيانات التعريفية للملف الذي يتم تحميله أو البيانات التعريفية المحدثة لملف موجود. ويرتبط هذا بمتغير resource ، الذي يحتوي على بيانات تعريف الملف الحالية في المسار المطلوب، بدلاً من بيانات التعريف الجديدة.

// Allow a request if the new value is smaller than 5MB
allow read, write: if request.resource.size < 5 * 1024 * 1024;

يحتوي request.resource على الخصائص التالية من resource :

ملكية
name
bucket
metadata
size
contentType

time

يحتوي متغير time على طابع زمني يمثل وقت الخادم الحالي الذي يتم تقييم الطلب فيه. يمكنك استخدام هذا لتوفير الوصول المستند إلى الوقت إلى الملفات، مثل: السماح فقط بتحميل الملفات حتى تاريخ معين، أو السماح فقط بقراءة الملفات لمدة تصل إلى ساعة بعد تحميلها.

// Allow a read if the file was created less than one hour ago
allow read: if request.time < resource.timeCreated + duration.value(1, 'h');

يتم توفير العديد من الوظائف لكتابة القواعد باستخدام الطوابع الزمنية والمدد .

الموارد

يحتوي متغير resource على بيانات تعريف الملف للملفات الموجودة في Cloud Storage، مثل اسم الملف وحجمه ووقت الإنشاء وبيانات التعريف المخصصة.

ملكيات

name

سلسلة تحتوي على الاسم الكامل للملف، بما في ذلك المسار إلى الملف.

// Allow reads if the resource name is "path/to/object"
allow read: if resource.name == 'path/to/object'

bucket

سلسلة تحتوي على مجموعة Google Cloud Storage التي يتم تخزين هذا الملف فيها.

// Allow reads of all resources in your bucket
allow read: if resource.bucket == '<your-cloud-storage-bucket>'

generation

ملف يحتوي على إنشاء كائن Google Cloud Storage للملف. تستخدم لإصدار الكائن.

// Allow reads if the resource matches a known object version
allow read: if resource.generation == <known-generation>

metageneration

ملف يحتوي على إنشاء كائن Google Cloud Storage للملف. تستخدم لإصدار الكائن.

// Allow reads if the resource matches a known object metadata version
allow read: if resource.metageneration == <known-generation>

size

int يحتوي على حجم الملف بالبايت.

// Allow reads if the resource is less than 10 MB
allow read: if resource.size < 10 * 1024 * 1024;

timeCreated

طابع زمني يمثل وقت إنشاء الملف.

// Allow reads if the resource was created less than an hour ago
allow read: if resource.timeCreated < request.time + duration.value(60, "m")

updated

طابع زمني يمثل تاريخ آخر تحديث للملف.

// Allow reads if the resource was updated less than an hour ago
allow read: if resource.updated < request.time + duration.value(60, "m")

md5Hash

سلسلة تحتوي على تجزئة MD5 للملف.

// Allow writes if the hash of the uploaded file is the same as the existing file
allow write: if request.resource.md5Hash == resource.md5Hash;

crc32c

سلسلة تحتوي على تجزئة crc32c للملف.

// Allow writes if the hash of the uploaded file is the same as the existing file
allow write: if request.resource.crc32c == resource.crc32c;

etag

سلسلة تحتوي على علامة الملف.

// Allow writes if the etag matches a known object etag
allow write: if resource.etag == <known-generation>

contentDisposition

سلسلة تحتوي على ترتيب محتوى الملف.

// Allow reads if the content disposition matches a certain value
allow read: if resource.contentDisposition == 'inlined';

contentEncoding

سلسلة تحتوي على ترميز محتوى الملف.

// Allow reads if the content is encoded with gzip
allow read: if resource.contentEncoding == 'gzip';

contentLanguage

سلسلة تحتوي على لغة محتوى الملف.

// Allow reads if the content language is Japanese
allow read: if resource.contentLanguage == 'ja';

contentType

سلسلة تحتوي على نوع محتوى الملف.

// Allow reads if the content type is PNG.
allow read: if resource.contentType == 'image/png';

metadata

Map<String, String> تحتوي على حقول البيانات الوصفية الإضافية المقدمة من المطور.

// Allow reads if a certain metadata field matches a desired value
allow read: if resource.metadata.customProperty == 'customValue';

firestore.get وfirestore.exists

تسمح لك الدالتان firestore.get() و firestore.exists() بالوصول إلى المستندات في Cloud Firestore لتقييم معايير الترخيص المعقدة.

تتوقع الدالتان firestore.get() و firestore.exists() مسارات مستند محددة بالكامل. عند استخدام المتغيرات لإنشاء مسارات لـ firestore.get() و firestore.exists() ، فإنك تحتاج إلى الهروب من المتغيرات بشكل صريح باستخدام بناء الجملة $(variable) .

firestore.get

احصل على محتويات مستند Cloud Firestore.

service firebase.storage {
  match /b/{bucket}/o {
    match /users/{club}/files/{fileId} {
      allow read: if club in
        firestore.get(/databases/(default)/documents/users/$(request.auth.uid)).data.memberships
    }
  }
}

firestore.exists

تحقق من وجود مستند Cloud Firestore.

service firebase.storage {
  match /b/{bucket}/o {
    match /users/{userId}/photos/{fileId} {
      allow read: if
        firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.uid))
    }
  }
}

خدمة

service هي أول إعلان في ملف قواعد أمان التخزين السحابي، وتحدد الخدمة التي ستنطبق عليها هذه القواعد.

اسم

name

سيتم تطبيق قواعد الخدمة على الاسم. القيمة الحالية الوحيدة هي firebase.storage .

// Specify the service name
service firebase.storage {
  match /b/{bucket}/o {
    ...
  }
}

أنواع البيانات

تسمح لك لغة القواعد بالتحقق من الكتابة باستخدام is التشغيل.

// For example
a is null
a is string

null

يمثل نوع البيانات null قيمة غير موجودة.

allow read: if request.auth != null;

bool

يمثل نوع bool قيمة منطقية true أو false .

allow read: if true;   // always succeeds
allow write: if false; // always fails

مقارنة

يمكن مقارنة القيم المنطقية باستخدام عوامل التشغيل == != .

العمليات المنطقية

عملية تعبير
AND x && y
OR x || y
NOT !x

عمليات الدائرة القصيرة، ويمكن أن ترجع إما true أو false أو خطأ .

allow read: if true || false;   // always succeeds, short circuits at true
allow write: if false && true; // always fails, short circuits at false

int float

يمثل النوعان int و float أرقامًا. Ints هي: 0 ، 1 ، -2 ، وما إلى ذلك، بينما العوامات هي: 1.0 ، -2.0 ، 3.33 ، إلخ.

Ints هي قيم 64 بت موقعة، والعوامات هي قيم متوافقة مع IEEE 754 64 بت. سيتم إجبار قيم النوع int على float عند استخدامها في المقارنات والعمليات الحسابية ذات القيمة float .

مقارنة

يمكن مقارنة وترتيب ints و floats باستخدام عوامل التشغيل == != > و < و >= و <= .

علم الحساب

يمكن إضافة العناصر والعوامات وطرحها وضربها وتقسيمها وتعديلها وإبطالها:

عملية تعبير
إضافة x + y
الطرح x - y
عمليه الضرب x * y
قسم x / y
مودولو x % y
النفي -x

الوظائف الرياضية

توفر قواعد أمان Firebase للتخزين السحابي أيضًا عددًا من الوظائف المساعدة في الرياضيات لتبسيط التعبيرات:

وظيفة وصف
math.ceil(x) سقف القيمة الرقمية
math.floor(x) أرضية القيمة الرقمية
math.round(x) قم بتقريب قيمة الإدخال إلى أقرب عدد صحيح
math.abs(x) القيمة المطلقة للمدخلات
math.isInfinite(x) اختبار ما إذا كانت القيمة هي ±∞ ، وإرجاع bool
math.isNaN(x) اختبار ما إذا كانت القيمة ليست رقمًا NaN ، وإرجاع bool

string

مقارنة

يمكن مقارنة السلاسل النصية وترتيبها معجميًا باستخدام عوامل التشغيل == و != > و < و >= و <= .

سلسلة

يمكن ربط السلاسل باستخدام عامل التشغيل + .

// Concatenate a file name and extension
'file' + '.txt'

الفهرس والمدى

يقوم عامل index ، string[] ، بإرجاع سلسلة تحتوي على الحرف الموجود في الفهرس المقدم في السلسلة.

// Allow reads of files that begin with 'a'
match /{fileName} {
  allow read: if fileName[0] == 'a';
}

يُرجع عامل range ، string[i:j] ، سلسلة تحتوي على الأحرف بين الفهارس المحددة، من i (شامل) حتى j (حصريًا). إذا لم يتم تحديد i أو j ، فسيتم تعيينهما افتراضيًا على 0 وحجم السلسلة، على التوالي، ولكن يجب تحديد i أو j على الأقل حتى يكون النطاق صالحًا.

// Allow reads of files that begin with 'abcdef'
match /{fileName} {
  allow read: if fileName[0:6] == 'abcdef';
}

سوف ينتج عن عوامل تشغيل index range خطأ إذا تجاوزت المؤشرات المقدمة حدود السلسلة.

size

إرجاع عدد الأحرف في السلسلة.

// Allow files with names less than 10 characters
match /{fileName} {
  allow write: if fileName.size() < 10;
}

matches

ينفذ مطابقة التعبير العادي، ويعيد true إذا كانت السلسلة تطابق التعبير العادي المحدد. يستخدم بناء جملة Google RE2 .

// Allow writes to files which end in ".txt"
match /{fileName} {
  allow write: if fileName.matches('.*\\.txt')
}

split

يقسم سلسلة وفقًا للتعبير العادي المقدم ويعيد list السلاسل. يستخدم بناء جملة Google RE2 .

// Allow files named "file.*" to be uploaded
match /{fileName} {
  allow write: if fileName.split('.*\\..*')[0] == 'file'
}

path

المسارات هي أسماء تشبه الدليل مع مطابقة نمط اختيارية. يشير وجود شرطة مائلة للأمام / إلى بداية مقطع المسار.

path

يحول وسيطة string إلى path .

// Allow reads on a specific file path
match /{allFiles=**} {
  allow read: if allFiles == path('/path/to/file');
}

timestamp

الطوابع الزمنية موجودة بالتوقيت العالمي المنسق (UTC)، مع القيم المحتملة التي تبدأ عند 0001-01-01T00.00.00Z وتنتهي عند 9999-12-31T23.59.59Z.

مقارنة

يمكن مقارنة الطوابع الزمنية وترتيبها باستخدام عوامل التشغيل == و != > و < و >= و <= .

علم الحساب

تدعم الطوابع الزمنية الجمع والطرح بين الطوابع الزمنية والمدد كما يلي:

تعبير نتيجة
timestamp + duration timestamp
duration + timestamp timestamp
timestamp - duration timestamp
timestamp - timestamp duration
duration + duration duration
duration - duration duration

date

قيمة timestamp تحتوي على year month day فقط.

// Allow reads on the same day that the resource was created.
allow read: if request.time.date() == resource.timeCreated.date()

year

قيمة السنة كقيمة int، من 1 إلى 9999.

// Allow reads on all requests made before 2017
allow read: if request.time.year() < 2017

month

قيمة الشهر كقيمة int، من 1 إلى 12.

// Allow reads on all requests made during the month of January
allow read: if request.time.month() == 1;

day

اليوم الحالي من الشهر كـ int، من 1 إلى 31.

// Allow reads on all requests made during the first day of each month
allow read: if request.time.day() == 1;

time

قيمة duration التي تحتوي على الوقت الحالي.

// Allow reads on all requests made before 12PM
allow read: if request.time.time() < duration.time(12, 0, 0, 0);

hours

قيمة الساعات كـ int، من 0 إلى 23.

// Allow reads on all requests made before 12PM
allow read: if request.time.hours() < 12;

minutes

قيمة الدقائق هي int، من 0 إلى 59.

// Allow reads during even minutes of every hour
allow read: if request.time.minutes() % 2 == 0;

seconds

قيمة الثواني كقيمة int، من 0 إلى 59.

// Allow reads during the second half of each minute
allow read: if request.time.seconds() > 29;

nanos

الثواني الكسرية في النانو كعدد صحيح.

// Allow reads during the first 0.1 seconds of each second
allow read: if request.time.nanos() < 100000000;

dayOfWeek

يوم الأسبوع من 1 (الاثنين) إلى 7 (الأحد).

// Allow reads on weekdays (Monday to Friday)
allow read: if request.time.dayOfWeek() < 6;

dayOfYear

اليوم من العام الحالي من 1 إلى 366.

// Allow reads every fourth day
allow read: if request.time.dayOfYear() % 4 == 0;

toMillis

إرجاع العدد الحالي من المللي ثانية منذ عصر يونكس.

// Allow reads if the request is made before a specified time
allow read: if request.time.toMillis() < <milliseconds>;

duration

يتم تمثيل قيم المدة بالثواني بالإضافة إلى الثواني الكسرية بالنانو ثانية.

مقارنة

يمكن مقارنة الفترات وترتيبها باستخدام عوامل التشغيل == و != > و < و >= و <= .

علم الحساب

تدعم المُدد الجمع والطرح بين الطوابع الزمنية والمدد كما يلي:

تعبير نتيجة
timestamp + duration timestamp
duration + timestamp timestamp
timestamp - duration timestamp
timestamp - timestamp duration
duration + duration duration
duration - duration duration

seconds

عدد الثواني في المدة الحالية. يجب أن يكون بين -315,576,000,000 و+315,576,000,000 شاملاً.

nanos

عدد الثواني الكسرية (بالنانو ثانية) من المدة الحالية. يجب أن يكون بين -999,999,999 و+999,999,999 شاملاً. بالنسبة للثواني غير الصفرية والنانو ثانية غير الصفرية، يجب أن تكون إشارتاهما متفقتين.

duration.value

يمكن إنشاء المُدد باستخدام وظيفة duration.value(int magnitude, string units) ، التي تنشئ مدة زمنية من المقدار والوحدة المحددين.

// All of these durations represent one hour:
duration.value(1, "h")
duration.value(60, "m")
duration.value(3600, "s")

unit المحتملة هي:

مدة unit
أسابيع w
أيام d
ساعات h
دقائق m
ثواني s
ميلي ثانية ms
نانو ثانية ns

duration.time

يمكن إنشاء المدد باستخدام وظيفة duration.time(int hours, int minutes, int seconds, int nanoseconds) وظيفة، والتي تنشئ مدة زمنية للساعات والدقائق والثواني والنانوثانية المحددة.

// Create a four hour, three minute, two second, one nanosecond duration
duration.time(4, 3, 2, 1)

list

تحتوي القائمة على مصفوفة مرتبة من القيم، والتي يمكن أن تكون من النوع: null أو bool أو int أو float أو string أو path أو list أو map أو timestamp أو duration .

بالنظر إلى x و y من list النوع و i و j من النوع int

خلق

لإنشاء قائمة، قم بإضافة القيم بين قوسين:

// Create a list of strings
['apples', 'grapes', 'bananas', 'cheese', 'goats']

مقارنة

يمكن مقارنة القوائم باستخدام عوامل التشغيل == != . تتطلب المساواة بين قائمتين أن تكون جميع القيم متساوية.

الفهرس والمدى

يقوم عامل index ، list[] ، بإرجاع العنصر الموجود في الفهرس المقدم في القائمة.

// Allow reads of all files that begin with 'a'
match /{fileName} {
  allow read: if fileName[0] == 'a';
}

يقوم عامل range ، list[i:j] ، بإرجاع جميع العناصر الموجودة في القائمة بين المؤشرات المحددة، من i (شامل) حتى j (حصريًا). إذا لم يتم تحديد i أو j ، فسيتم تعيينهما افتراضيًا على 0 وحجم القائمة، على التوالي، ولكن يجب تحديد i أو j على الأقل حتى يكون النطاق صالحًا.

// Allow reads of all files that begin with 'abcdef'
match /{fileName} {
  allow read: if fileName[0:6] == 'abcdef';
}

in

يُرجع true إذا كانت القيمة المطلوبة موجودة في القائمة أو false إذا لم يكن موجودًا.

// Allow read if a filename has the string 'txt' in it
match /{fileName} {
  allow read: if 'txt' in fileName.split('\\.');
}

join

يجمع قائمة من السلاسل في سلسلة واحدة، مفصولة بالسلسلة المحددة.

// Allow reads if the joined array is 'file.txt'
allow read: if ['file', 'txt'].join('.') == 'file.txt';

size

عدد العناصر في القائمة.

// Allow read if there are three items in our list
allow read: if ['foo', 'bar', 'baz'].size() == 3;

hasAll

يُرجع true إذا كانت جميع القيم موجودة في القائمة.

// Allow read if one list has all items in the other list
allow read: if ['file', 'txt'].hasAll(['file', 'txt']);

map

تحتوي الخريطة على أزواج المفاتيح/القيم، حيث المفاتيح عبارة عن سلاسل والقيم يمكن أن تكون أيًا من: null أو bool أو int أو float أو string أو path أو list أو map أو timestamp أو duration .

خلق

لإنشاء خريطة، قم بإضافة أزواج المفاتيح/القيمات بين الأقواس:

// Create a map of strings to strings
{
  'mercury': 'mars',
  'rain': 'cloud',
  'cats': 'dogs',
}

مقارنة

يمكن مقارنة الخرائط باستخدام عوامل التشغيل == != . تتطلب مساواة خريطتين وجود جميع المفاتيح في كلتا الخريطتين وأن تكون جميع القيم متساوية.

فِهرِس

يتم الوصول إلى القيم الموجودة في الخريطة باستخدام إما قوس أو نقطة:

// Access custom metadata properties
allow read: if resource.metadata.property == 'property'
allow write: if resource.metadata['otherProperty'] == 'otherProperty'

في حالة عدم وجود المفتاح، سيتم إرجاع error .

in

يُرجع true إذا كان المفتاح المطلوب موجودًا في الخريطة أو false إذا لم يكن موجودًا.

// Allow reads if a property is present in the custom metadata
allow read: if property in resource.metadata;

size

عدد المفاتيح في الخريطة

// Allow reads if there's exactly one custom metadata key
allow read: if resource.metadata.size() == 1;

keys

قائمة بجميع المفاتيح الموجودة في الخريطة.

// Allow reads if the first metadata key is 'myKey'
allow read: if resource.metadata.keys()[0] == 'myKey';

values

قائمة بجميع القيم في الخريطة، بترتيب المفاتيح.

// Allow reads if the first metadata value is 'myValue'
allow read: if resource.metadata.values()[0] == 'myValue';

أخطاء

تقييم الخطأ

تستمر قواعد أمان Firebase للتخزين السحابي في التقييم عند مواجهة أخطاء. وهذا مفيد لأن && و || مشروط قد تمتص التعبيرات خطأً إذا كان الشرط الشرطي سيؤدي إلى قصر الدائرة إلى false أو true على التوالي. على سبيل المثال:

تعبير نتيجة
error && true error
error && false false
error || true true
error || false error

الأماكن الشائعة التي تظهر فيها الأخطاء هي: القسمة على صفر، والوصول إلى قيم غير موجودة في قائمة أو خريطة، وتمرير قيم من النوع غير الصحيح إلى دالة.

// Error if resource.size is zero
allow read: if 1000000 / resource.size;

// Error, key doesn't exist
allow read: if resource.metadata.nonExistentKey == 'value';

// Error, no unit 'y' exists
allow read: if request.time < resource.timeCreated + duration.value(1, 'y');