تأكيد صحة البيانات

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

حدد منتجًا في كل قسم لمعرفة المزيد حول قواعد التحقق من صحة البيانات.

قيود على البيانات الجديدة

سحابة Firestore

إذا كنت تريد التأكد من عدم إنشاء مستند يحتوي على حقل معين ، يمكنك تضمين الحقل في شرط allow . على سبيل المثال ، إذا كنت تريد رفض إنشاء أي مستندات تحتوي على حقل ranking ، فلن تسمح بذلك في شرط create .

  service cloud.firestore {
    match /databases/{database}/documents {
      // Disallow
      match /cities/{city} {
        allow create: if !("ranking" in request.resource.data)
      }
    }
  }

قاعدة بيانات الوقت الفعلي

إذا كنت تريد التأكد من عدم إضافة البيانات التي تحتوي على قيم معينة إلى قاعدة البيانات الخاصة بك ، فيمكنك تضمين هذه القيمة في القواعد الخاصة بك وعدم السماح لها بالكتابة. على سبيل المثال ، إذا كنت تريد رفض أي كتابات تحتوي على قيم ranking ، فلن تسمح بالكتابة لأي مستندات ذات قيم ranking .

  {
    "rules": {
      // Write is allowed for all paths
      ".write": true,
      // Allows writes only if new data doesn't include a `ranking` child value
      ".validate": "!newData.hasChild('ranking')
    }
  }

سحابة التخزين

إذا كنت تريد التأكد من عدم إنشاء ملف يحتوي على بيانات وصفية معينة ، يمكنك تضمين البيانات الأولية في شرط allow . على سبيل المثال ، إذا كنت تريد رفض إنشاء أي ملفات تحتوي على بيانات ranking ، فلن تسمح بذلك في شرط create .

  service firebase.storage {
    match /b/{bucket}/o {
      match /files/{allFiles=**} {
      // Disallow
        allow create: if !("ranking" in request.resource.metadata)
      }
    }
  }

استخدم البيانات الموجودة في قواعد أمان Firebase

سحابة Firestore

تخزن العديد من التطبيقات معلومات التحكم في الوصول كحقول في المستندات في قاعدة البيانات. يمكن لقواعد أمان Cloud Firestore السماح بالوصول أو رفضه ديناميكيًا استنادًا إلى بيانات المستند:

  service cloud.firestore {
    match /databases/{database}/documents {
      // Allow the user to read data if the document has the 'visibility'
      // field set to 'public'
      match /cities/{city} {
        allow read: if resource.data.visibility == 'public';
      }
    }
  }

يشير متغير resource إلى المستند المطلوب ، بينما resource.data عبارة عن خريطة لجميع الحقول والقيم المخزنة في المستند. لمزيد من المعلومات حول متغير resource ، راجع الوثائق المرجعية .

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

   service cloud.firestore {
     match /databases/{database}/documents {
      // Make sure all cities have a positive population and
      // the name is not changed
      match /cities/{city} {
        allow update: if request.resource.data.population > 0
                      && request.resource.data.name == resource.data.name;
      }
    }
  }

قاعدة بيانات الوقت الفعلي

في Realtime Database ، استخدم قواعد .validate لفرض هياكل البيانات والتحقق من صحة تنسيق البيانات ومحتواها. تقوم القواعد بتشغيل .validate التحقق من صحة القواعد بعد التحقق من أن قاعدة .write تمنح الوصول.

لا تتالي قواعد .validate الصحة. إذا فشلت أي قاعدة تحقق من الصحة على أي مسار أو مسار فرعي في القاعدة ، فسيتم رفض عملية الكتابة بأكملها. بالإضافة إلى ذلك ، فإن تعريفات التحقق من الصحة تتحقق فقط من القيم غير الفارغة ، وتتجاهل بالتالي أي طلبات تحذف البيانات.

ضع في اعتبارك قواعد .validate التالية:

  {
    "rules": {
      // write is allowed for all paths
      ".write": true,
      "widget": {
        // a valid widget must have attributes "color" and "size"
        // allows deleting widgets (since .validate is not applied to delete rules)
        ".validate": "newData.hasChildren(['color', 'size'])",
        "size": {
          // the value of "size" must be a number between 0 and 99
          ".validate": "newData.isNumber() &&
                        newData.val() >= 0 &&
                        newData.val() <= 99"
        },
        "color": {
          // the value of "color" must exist as a key in our mythical
          // /valid_colors/ index
          ".validate": "root.child('valid_colors/' + newData.val()).exists()"
        }
      }
    }
  }

ستؤدي طلبات الكتابة إلى قاعدة بيانات بالقواعد المذكورة أعلاه إلى النتائج التالية:

جافا سكريبت
var ref = db.ref("/widget");

// PERMISSION_DENIED: does not have children color and size
ref.set('foo');

// PERMISSION DENIED: does not have child color
ref.set({size: 22});

// PERMISSION_DENIED: size is not a number
ref.set({ size: 'foo', color: 'red' });

// SUCCESS (assuming 'blue' appears in our colors list)
ref.set({ size: 21, color: 'blue'});

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child('size').set(99);
ج موضوعية
ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
FIRDatabaseReference *ref = [[[FIRDatabase database] reference] child: @"widget"];

// PERMISSION_DENIED: does not have children color and size
[ref setValue: @"foo"];

// PERMISSION DENIED: does not have child color
[ref setValue: @{ @"size": @"foo" }];

// PERMISSION_DENIED: size is not a number
[ref setValue: @{ @"size": @"foo", @"color": @"red" }];

// SUCCESS (assuming 'blue' appears in our colors list)
[ref setValue: @{ @"size": @21, @"color": @"blue" }];

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
[[ref child:@"size"] setValue: @99];
سويفت
ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
var ref = FIRDatabase.database().reference().child("widget")

// PERMISSION_DENIED: does not have children color and size
ref.setValue("foo")

// PERMISSION DENIED: does not have child color
ref.setValue(["size": "foo"])

// PERMISSION_DENIED: size is not a number
ref.setValue(["size": "foo", "color": "red"])

// SUCCESS (assuming 'blue' appears in our colors list)
ref.setValue(["size": 21, "color": "blue"])

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child("size").setValue(99);
جافا
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("widget");

// PERMISSION_DENIED: does not have children color and size
ref.setValue("foo");

// PERMISSION DENIED: does not have child color
ref.child("size").setValue(22);

// PERMISSION_DENIED: size is not a number
Map<String,Object> map = new HashMap<String, Object>();
map.put("size","foo");
map.put("color","red");
ref.setValue(map);

// SUCCESS (assuming 'blue' appears in our colors list)
map = new HashMap<String, Object>();
map.put("size", 21);
map.put("color","blue");
ref.setValue(map);

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child("size").setValue(99);
استراحة
# PERMISSION_DENIED: does not have children color and size
curl -X PUT -d 'foo' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# PERMISSION DENIED: does not have child color
curl -X PUT -d '{"size": 22}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# PERMISSION_DENIED: size is not a number
curl -X PUT -d '{"size": "foo", "color": "red"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# SUCCESS (assuming 'blue' appears in our colors list)
curl -X PUT -d '{"size": 21, "color": "blue"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# If the record already exists and has a color, this will
# succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
# will fail to validate
curl -X PUT -d '99' \
https://docs-examples.firebaseio.com/rest/securing-data/example/size.json

سحابة التخزين

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

يحتوي كائن resource على أزواج مفتاح / قيمة مع ظهور بيانات وصفية للملف في كائن التخزين السحابي. يمكن فحص هذه الخصائص في طلبات read أو write لضمان سلامة البيانات. يتحقق كائن resource من البيانات الوصفية للملفات الموجودة في حاوية Cloud Storage.

  service firebase.storage {
    match /b/{bucket}/o {
      match /images {
        match /{allImages=**} {
          // Allow reads if a custom 'visibility' field is set to 'public'
          allow read: if resource.metadata.visibility == 'public';
        }
      }
    }
  }

يمكنك أيضًا استخدام كائن request.resource في طلبات write (مثل عمليات التحميل وتحديثات البيانات الوصفية والحذف. يحصل كائن request.resource على بيانات وصفية من الملف الذي سيتم كتابته إذا كان مسموحًا write .

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

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

تتوفر قائمة كاملة بالخصائص في كائن resource في الوثائق المرجعية .