การตรวจสอบข้อมูล

คุณสามารถใช้ Firebase Security Rules เพื่อเขียนข้อมูลใหม่แบบมีเงื่อนไขโดยอิงตามข้อมูลที่มีอยู่ในฐานข้อมูลหรือที่เก็บข้อมูลได้ นอกจากนี้ คุณยังเขียนกฎที่บังคับใช้การตรวจสอบข้อมูลได้โดยจำกัดการเขียนตามข้อมูลใหม่ที่เขียน อ่านต่อเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับกฎที่ใช้ข้อมูลที่มีอยู่เพื่อสร้างเงื่อนไขด้านความปลอดภัย

เลือกผลิตภัณฑ์ในแต่ละส่วนเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับกฎการตรวจสอบข้อมูล

หากต้องการความช่วยเหลือจาก AI ให้คัดลอกพรอมต์ด้านล่างลงในตัวแทนการเขียนโค้ด AI (เช่น Gemini ใน Android Studio, Antigravity, Claude Code, Codex และ Cursor) คุณสามารถปรับแต่งพรอมต์และทำซ้ำกับ Agent ได้ ดูข้อมูลการติดตั้งโดยละเอียดได้ที่ทักษะเอเจนต์ 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.

ข้อจำกัดเกี่ยวกับข้อมูลใหม่

Cloud Firestore

หากต้องการตรวจสอบว่าไม่มีการสร้างเอกสารที่มีฟิลด์ที่เฉพาะเจาะจง คุณสามารถรวมฟิลด์นั้นไว้ในเงื่อนไข allow ได้ เช่น หากต้องการปฏิเสธการสร้างเอกสารที่มีช่อง ranking คุณจะต้องไม่อนุญาตในเงื่อนไข create

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

Realtime Database

หากต้องการตรวจสอบว่าข้อมูลที่มีค่าบางอย่างไม่ได้เพิ่มลงในฐานข้อมูล คุณจะต้องรวมค่านั้นไว้ในกฎและไม่อนุญาตให้เขียน ตัวอย่างเช่น หากต้องการปฏิเสธการเขียนที่มีค่า 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')
    }
  }

Cloud Storage

หากต้องการตรวจสอบว่าไม่มีการสร้างไฟล์ที่มีข้อมูลเมตาที่เฉพาะเจาะจง คุณสามารถรวมข้อมูลเมตาดังกล่าวไว้ในเงื่อนไข allow ได้ เช่น หากต้องการปฏิเสธการสร้างไฟล์ที่มีข้อมูลเมตา ranking คุณจะต้องไม่อนุญาตในเงื่อนไข create

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

ใช้ข้อมูลที่มีอยู่ใน Firebase Security Rules

Cloud Firestore

แอปจำนวนมากจัดเก็บข้อมูลการควบคุมการเข้าถึงเป็นฟิลด์ในเอกสารในฐานข้อมูล Cloud Firestore Security Rules สามารถอนุญาตหรือปฏิเสธการเข้าถึงแบบไดนามิกตามข้อมูลเอกสารได้ดังนี้

  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 ได้ที่เอกสารอ้างอิง

เมื่อเขียนข้อมูล คุณอาจต้องการเปรียบเทียบข้อมูลขาเข้ากับข้อมูลที่มีอยู่ ซึ่งจะช่วยให้คุณดำเนินการต่างๆ ได้ เช่น ตรวจสอบว่าช่องไม่มีการเปลี่ยนแปลง ช่องเพิ่มขึ้นเพียง 1 ช่อง หรือค่าใหม่อยู่ในอนาคตอย่างน้อย 1 สัปดาห์ ในกรณีนี้ หากชุดกฎอนุญาตให้เขียนที่รอดำเนินการ ตัวแปร 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

ใน Realtime Database ให้ใช้กฎ .validate เพื่อบังคับใช้โครงสร้างข้อมูลและตรวจสอบความถูกต้องของรูปแบบและเนื้อหาของข้อมูล Security Rules จะเรียกใช้กฎ .validate หลังจากยืนยันว่ากฎ .write ให้สิทธิ์เข้าถึง

กฎ .validate จะไม่มีผลแบบต่อกันเป็นทอดๆ หากกฎการตรวจสอบไม่สำเร็จในเส้นทางหรือเส้นทางย่อยใดๆ ในกฎ ระบบจะปฏิเสธการดำเนินการเขียนทั้งหมด นอกจากนี้ คำจำกัดความของการตรวจสอบจะตรวจสอบเฉพาะค่าที่ไม่ใช่ค่า Null และจะละเว้นคำขอที่ลบข้อมูลในภายหลัง

ลองพิจารณากฎ .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()"
        }
      }
    }
  }

คำขอเขียนไปยังฐานข้อมูลที่มีกฎก่อนหน้าจะมีผลลัพธ์ดังต่อไปนี้

JavaScript
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);
Objective-C
หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
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];
Swift
หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
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);
Java
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);
REST
# 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

Cloud Storage

เมื่อประเมินกฎ คุณอาจต้องประเมินข้อมูลเมตาของไฟล์ที่อัปโหลด ดาวน์โหลด แก้ไข หรือลบด้วย ซึ่งจะช่วยให้คุณสร้างกฎที่ซับซ้อนและมีประสิทธิภาพซึ่งทำสิ่งต่างๆ ได้ เช่น อนุญาตให้อัปโหลดเฉพาะไฟล์ที่มีเนื้อหาบางประเภท หรือลบเฉพาะไฟล์ที่มีขนาดใหญ่กว่าขนาดที่กำหนด

ออบเจ็กต์ resource มีคู่คีย์-ค่าพร้อมข้อมูลเมตาของไฟล์ที่แสดงในออบเจ็กต์ Cloud Storage คุณสามารถตรวจสอบพร็อพเพอร์ตี้เหล่านี้ได้ในคำขอ read หรือ write เพื่อให้มั่นใจว่าข้อมูลมีความสมบูรณ์ของข้อมูล ออบเจ็กต์ resource จะตรวจสอบข้อมูลเมตาของไฟล์ที่มีอยู่ในที่เก็บข้อมูล Cloud Storage

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

นอกจากนี้ คุณยังใช้ออบเจ็กต์ request.resource ในคำขอ write (เช่น การอัปโหลด การอัปเดตข้อมูลเมตา และการลบ) ได้ด้วย ออบเจ็กต์ request.resource จะได้รับข้อมูลเมตาจากไฟล์ที่จะเขียนหากอนุญาตให้ใช้ write

คุณสามารถใช้ค่าทั้ง 2 ค่านี้เพื่อป้องกันการอัปเดตที่ไม่ต้องการหรือไม่สอดคล้องกัน หรือเพื่อบังคับใช้ข้อจำกัดของแอปพลิเคชัน เช่น ประเภทไฟล์ หรือขนาดไฟล์

  service firebase.storage {
    match /b/{bucket}/o {
      match /images {
        // 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) Filename (stored in imageId wildcard variable) is less than 32 characters
        match /{imageId} {
          allow read;
          allow write: if request.resource.size < 5 * 1024 * 1024
                       && request.resource.contentType.matches('image/.*')
                       && request.resource.contentType == resource.contentType
                       && imageId.size() < 32
        }
      }
    }
  }

ดูรายการพร็อพเพอร์ตี้ทั้งหมดในออบเจ็กต์ resource ได้ในเอกสารอ้างอิง