Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Cách thức hoạt động của Quy tắc bảo mật

Bảo mật có thể là một trong những phần phức tạp nhất của câu đố phát triển ứng dụng. Trong hầu hết các ứng dụng, các nhà phát triển phải xây dựng và chạy một máy chủ xử lý xác thực (người dùng là ai) và ủy quyền (người dùng có thể làm gì).

Quy tắc bảo mật của Firebase loại bỏ lớp giữa (máy chủ) và cho phép bạn chỉ định quyền dựa trên đường dẫn cho các ứng dụng khách kết nối trực tiếp với dữ liệu của bạn. Sử dụng hướng dẫn này để tìm hiểu thêm về cách các quy tắc được áp dụng cho các yêu cầu đến.

Chọn một sản phẩm để tìm hiểu thêm về các quy tắc của nó.

Cloud Firestore

Cấu trúc cơ bản

Quy tắc bảo mật Firebase trong Cloud Firestore và Cloud Storage sử dụng cấu trúc và cú pháp sau:

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

Các khái niệm chính sau đây rất quan trọng cần hiểu khi bạn xây dựng các quy tắc:

  • Yêu cầu: Các phương pháp hoặc các phương pháp áp dụng trong các allow tuyên bố. Đây là những phương pháp bạn đang cho phép chạy. Các phương pháp tiêu chuẩn là: get , list , create , update , và delete . Các readwrite các phương pháp tiện lợi cho phép rộng đọc và viết truy cập vào cơ sở dữ liệu hoặc lưu trữ đường dẫn cụ thể.
  • Đường dẫn: Cơ sở dữ liệu hoặc lưu trữ vị trí, biểu diễn dưới dạng một con đường URI.
  • Rule: Các allow tuyên bố, trong đó bao gồm một điều kiện cho phép yêu cầu nếu nó trả về true.

Quy tắc bảo mật phiên bản 2

Kể từ tháng 5 năm 2019, phiên bản 2 của quy tắc bảo mật Firebase hiện đã có sẵn. Phiên bản 2 của các quy tắc thay đổi hành vi của các ký tự đại diện đệ quy {name=**} . Bạn phải sử dụng phiên bản 2 nếu bạn có kế hoạch để sử dụng các truy vấn nhóm bộ sưu tập . Bạn phải chọn tham gia vào phiên bản 2 bằng cách làm cho rules_version = '2'; dòng đầu tiên trong quy tắc bảo mật của bạn:

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

Các con đường phù hợp

Tất cả các câu lệnh khớp phải trỏ đến tài liệu, không phải bộ sưu tập. Một tuyên bố trận đấu có thể trỏ đến một tài liệu cụ thể, như trong match /cities/SF hoặc sử dụng ký tự đại diện để trỏ đến bất kỳ tài liệu trong đường dẫn nhất định, như trong match /cities/{city} .

Trong ví dụ trên, báo cáo kết quả trận đấu sử dụng {city} cú pháp wildcard. Đây có nghĩa là các quy tắc áp dụng cho tài liệu nào ở các cities thu thập, chẳng hạn như /cities/SF hoặc /cities/NYC . Khi allow biểu thức trong báo cáo kết quả trận đấu được đánh giá, các city biến sẽ giải quyết để tên tài liệu thành phố như SF hay NYC .

Phù hợp với các bộ sưu tập phụ

Dữ liệu trong Cloud Firestore được sắp xếp thành các bộ sưu tập tài liệu và mỗi tài liệu có thể mở rộng hệ thống phân cấp thông qua các bộ sưu tập con. Điều quan trọng là phải hiểu cách các quy tắc bảo mật tương tác với dữ liệu phân cấp.

Hãy xem xét các tình huống mà mỗi tài liệu trong cities bộ sưu tập có chứa một landmarks subcollection. Quy tắc an ninh chỉ áp dụng tại đường dẫn phù hợp, do đó kiểm soát truy cập xác định trên cities thu không áp dụng cho các landmarks subcollection. Thay vào đó, hãy viết các quy tắc rõ ràng để kiểm soát quyền truy cập vào các bộ sưu tập con:

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

Khi làm tổ match tuyên bố, con đường của khu vực nội match tuyên bố luôn là liên quan đến con đường bên ngoài match tuyên bố. Do đó, các bộ quy tắc sau là tương đương:

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

Các ký tự đại diện đệ quy

Nếu bạn muốn quy tắc để áp dụng đối với một hệ thống phân cấp tùy tiện sâu, sử dụng cú pháp wildcard đệ quy, {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>;
    }
  }
}

Khi sử dụng cú pháp ký tự đại diện đệ quy, biến ký tự đại diện sẽ chứa toàn bộ đoạn đường dẫn phù hợp, ngay cả khi tài liệu nằm trong một bộ sưu tập con lồng nhau sâu. Ví dụ, các quy tắc nêu trên sẽ phù hợp với một tài liệu đặt tại /cities/SF/landmarks/coit_tower , và giá trị của các document biến sẽ SF/landmarks/coit_tower .

Tuy nhiên, lưu ý rằng hoạt động của các ký tự đại diện đệ quy phụ thuộc vào phiên bản quy tắc.

Phiên bản 1

Các quy tắc bảo mật sử dụng phiên bản 1 theo mặc định. Trong phiên bản 1, các ký tự đại diện đệ quy khớp với một hoặc nhiều mục đường dẫn. Họ không phù hợp với một con đường trống rỗng, vì vậy match /cities/{city}/{document=**} phù hợp với tài liệu trong bộ sưu tập con nhưng không phải trong cities bộ sưu tập, trong khi match /cities/{document=**} phù hợp với cả các tài liệu trong cities thu thập và bộ sưu tập con.

Các ký tự đại diện đệ quy phải ở cuối câu lệnh so khớp.

Phiên bản 2

Trong phiên bản 2 của quy tắc bảo mật, các ký tự đại diện đệ quy khớp với không hoặc nhiều mục đường dẫn. match/cities/{city}/{document=**} phù hợp với các văn bản trong bất kỳ bộ sưu tập con cũng như các tài liệu trong cities sưu tập.

Bạn phải chọn tham gia vào phiên bản 2 bằng cách thêm rules_version = '2'; ở đầu các quy tắc bảo mật của bạn:

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

Bạn có thể có nhiều nhất một ký tự đại diện đệ quy cho mỗi câu lệnh so khớp, nhưng trong phiên bản 2, bạn có thể đặt ký tự đại diện này ở bất kỳ đâu trong câu lệnh so khớp. Ví dụ:

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

Nếu bạn sử dụng các truy vấn nhóm bộ sưu tập , bạn phải sử dụng phiên bản 2, thấy bảo truy vấn nhóm bộ sưu tập .

Các câu lệnh trùng khớp

Có thể cho một tài liệu để phù hợp với nhiều hơn một match tuyên bố. Trong trường hợp nhiều allow biểu thức phù hợp với yêu cầu, việc tiếp cận được cho phép nếu một trong các điều kiện là 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;
    }
  }
}

Trong ví dụ trên, tất cả đọc và viết cho cities thu thập sẽ được phép vì sự cai trị thứ hai luôn luôn là true , mặc dù các quy tắc đầu tiên là luôn luôn false .

Giới hạn quy tắc bảo mật

Khi bạn làm việc với các quy tắc bảo mật, hãy lưu ý các giới hạn sau:

Giới hạn Thông tin chi tiết
Số lượng tối đa exists() , get() , và getAfter() gọi theo yêu cầu
  • 10 cho các yêu cầu một tài liệu và các yêu cầu truy vấn.
  • 20 cho nhiều lần đọc, giao dịch và ghi hàng loạt. Giới hạn trước đó là 10 cũng được áp dụng cho mỗi hoạt động.

    Ví dụ: hãy tưởng tượng bạn tạo một yêu cầu ghi hàng loạt với 3 thao tác ghi và các quy tắc bảo mật của bạn sử dụng 2 lệnh gọi truy cập tài liệu để xác thực mỗi lần ghi. Trong trường hợp này, mỗi lần ghi sử dụng 2 trong số 10 lệnh gọi truy cập của nó và yêu cầu ghi theo đợt sử dụng 6 trong số 20 lệnh gọi truy cập của nó.

Vượt quá một trong hai giới hạn dẫn đến lỗi bị từ chối cấp phép.

Một số cuộc gọi truy cập tài liệu có thể được lưu trong bộ nhớ cache và các cuộc gọi được lưu trong bộ nhớ cache không được tính vào giới hạn.

Lồng nhau tối đa match chiều sâu tuyên bố 10
Chiều dài đường truyền tối đa, trong các đoạn đường, cho phép trong một bộ lồng nhau match báo cáo 100
Số lượng tối đa các biến chụp đường cho phép trong một bộ lồng nhau match báo cáo 20
Độ sâu cuộc gọi chức năng tối đa 20
Số lượng tối đa các đối số của hàm 7
Số lượng tối đa let bindings biến mỗi chức năng 10
Số lượng lệnh gọi hàm đệ quy hoặc tuần hoàn tối đa 0 (không được phép)
Số lượng biểu thức tối đa được đánh giá cho mỗi yêu cầu 1.000
Kích thước tối đa của một bộ quy tắc Bộ quy tắc phải tuân theo hai giới hạn kích thước:
  • một giới hạn 256 KB vào kích thước của các nguồn văn bản ruleset xuất bản từ các căn cứ hỏa lực console hoặc từ CLI bằng firebase deploy .
  • giới hạn 250 KB về kích thước của bộ quy tắc đã biên dịch là kết quả khi Firebase xử lý nguồn và làm cho nó hoạt động trên back-end.

Lưu trữ đám mây

Cấu trúc cơ bản

Quy tắc bảo mật Firebase trong Cloud Firestore và Cloud Storage sử dụng cấu trúc và cú pháp sau:

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

Các khái niệm chính sau đây rất quan trọng cần hiểu khi bạn xây dựng các quy tắc:

  • Yêu cầu: Các phương pháp hoặc các phương pháp áp dụng trong các allow tuyên bố. Đây là những phương pháp bạn đang cho phép chạy. Các phương pháp tiêu chuẩn là: get , list , create , update , và delete . Các readwrite các phương pháp tiện lợi cho phép rộng đọc và viết truy cập vào cơ sở dữ liệu hoặc lưu trữ đường dẫn cụ thể.
  • Đường dẫn: Cơ sở dữ liệu hoặc lưu trữ vị trí, biểu diễn dưới dạng một con đường URI.
  • Rule: Các allow tuyên bố, trong đó bao gồm một điều kiện cho phép yêu cầu nếu nó trả về true.

Các con đường phù hợp

Đám mây Security Rules lưu trữ match các đường dẫn tập tin sử dụng để truy xuất file trong Cloud Storage. Nội quy có thể match đường dẫn chính xác hoặc đường dẫn wildcard, và các quy tắc cũng có thể được lồng vào nhau. Nếu không có quy tắc trận đấu cho phép một phương thức yêu cầu, hoặc đánh giá lại điều kiện để false , yêu cầu bị từ chối.

Đối sánh chính xác

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

Các trận đấu lồng vào nhau

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

Các trận đấu ký tự đại diện

Quy định cũng có thể được sử dụng để match một mô hình sử dụng ký tự đại diện. Một ký tự đại diện là một biến tên là đại diện hoặc là một chuỗi duy nhất như profilePhoto.png , hoặc nhiều đoạn đường, chẳng hạn như images/profilePhoto.png .

Một ký tự đại diện được tạo ra bằng cách thêm dấu ngoặc nhọn xung quanh tên ký tự đại diện, như {string} . Một đoạn ký tự đại diện nhiều thể được khai báo bằng cách thêm =** tên ký tự đại diện, như {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>;
  }
}

Nếu có nhiều quy tắc phù hợp với một tập tin, kết quả là OR về kết quả của tất cả các đánh giá quy định. Nghĩa là, nếu bất kỳ quy tắc tập tin phù hợp với evalutes để true , kết quả là true .

Trong các quy tắc trên, các tập tin "images / profilePhoto.png" có thể được đọc nếu một trong hai condition hoặc other_condition đánh giá là true, trong khi các tập tin "images / người dùng / user: 12345 / profilePhoto.png" chỉ là phụ thuộc vào kết quả của other_condition .

Một biến ký tự đại diện có thể được tham chiếu từ bên trong match cung cấp tên tập tin hoặc uỷ quyền đường dẫn:

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

Quy tắc bảo mật lưu trữ đám mây không phân tầng và quy tắc chỉ được đánh giá khi đường dẫn yêu cầu khớp với đường dẫn có quy tắc được chỉ định.

Yêu cầu đánh giá

Cập nhật, tải, thay đổi siêu dữ liệu, và xóa được đánh giá bằng cách sử dụng request gửi đến Cloud Storage. Các request biến chứa các đường dẫn tập tin nơi theo yêu cầu đang được thực hiện, thời gian khi yêu cầu được nhận, và mới resource giá trị nếu yêu cầu là một ghi. Tiêu đề HTTP và trạng thái xác thực cũng được bao gồm.

Các request đối tượng cũng chứa ID duy nhất của người dùng và các tải trọng căn cứ hỏa lực Authentication trong request.auth đối tượng, sẽ được giải thích thêm trong xác thực phần của tài liệu.

Một danh sách đầy đủ các thuộc tính trong request đối tượng có sẵn dưới đây:

Bất động sản Kiểu Sự miêu tả
auth map <string, string> Khi người dùng đăng nhập, cung cấp uid , ID của người dùng độc đáo, và token , bản đồ về tuyên bố căn cứ hỏa lực xác thực JWT. Nếu không, nó sẽ null .
params bản đồ <string, string> Bản đồ chứa các tham số truy vấn của yêu cầu.
path con đường Một path đại diện cho con đường yêu cầu đang được thực hiện tại.
resource map <string, string> Giá trị tài nguyên mới, chỉ trình bày trên write yêu cầu.
time dấu thời gian Dấu thời gian đại diện cho thời gian máy chủ mà yêu cầu được đánh giá tại.

Đánh giá tài nguyên

Khi đánh giá các quy tắc, bạn cũng có thể muốn đánh giá siêu dữ liệu của tệp đang được tải lên, tải xuống, sửa đổi hoặc xóa. Điều này cho phép bạn tạo các quy tắc phức tạp và mạnh mẽ để thực hiện những việc như chỉ cho phép các tệp có loại nội dung nhất định được tải lên hoặc chỉ các tệp lớn hơn một kích thước nhất định mới bị xóa.

Căn cứ hỏa lực Security Rules cho Cloud Storage cung cấp tập tin siêu dữ liệu trong resource đối tượng, trong đó có chứa các cặp giá trị / chủ chốt của siêu dữ liệu bề mặt trong một đối tượng Cloud Storage. Các tính chất này có thể được kiểm tra về read hoặc write các yêu cầu để đảm bảo tính toàn vẹn dữ liệu.

Trên write yêu cầu (ví dụ như cập nhật, cập nhật siêu dữ liệu, và xóa), ngoài các resource đối tượng, trong đó có chứa siêu dữ liệu tập tin cho file mà hiện đang tồn tại tại đường dẫn yêu cầu, bạn cũng có khả năng sử dụng request.resource đối tượng, trong đó chứa một tập hợp con của siêu dữ liệu tệp sẽ được ghi nếu việc ghi được cho phép. Bạn có thể sử dụng hai giá trị này để đảm bảo tính toàn vẹn của dữ liệu hoặc thực thi các ràng buộc ứng dụng như loại hoặc kích thước tệp.

Một danh sách đầy đủ các thuộc tính trong resource đối tượng có sẵn dưới đây:

Bất động sản Kiểu Sự miêu tả
name dây Tên đầy đủ của đối tượng
bucket dây Tên của thùng chứa đối tượng này.
generation NS Các thế hệ đối tượng Google Cloud Storage của đối tượng này.
metageneration NS Các đối tượng metageneration Google Cloud Storage của đối tượng này.
size NS Kích thước của đối tượng tính bằng byte.
timeCreated dấu thời gian Dấu thời gian biểu thị thời gian một đối tượng được tạo.
updated dấu thời gian Dấu thời gian đại diện cho thời gian một đối tượng được cập nhật lần cuối.
md5Hash dây Một băm MD5 của đối tượng.
crc32c dây Một hàm băm crc32c của đối tượng.
etag dây Etag liên kết với đối tượng này.
contentDisposition dây Sự bố trí nội dung liên quan đến đối tượng này.
contentEncoding dây Mã hóa nội dung được liên kết với đối tượng này.
contentLanguage dây Ngôn ngữ nội dung được liên kết với đối tượng này.
contentType dây Loại nội dung được liên kết với đối tượng này.
metadata map <string, string> Các cặp khóa / giá trị của siêu dữ liệu tùy chỉnh bổ sung, do nhà phát triển chỉ định.

request.resource chứa tất cả những việc này với ngoại lệ của generation , metageneration , etag , timeCreated , và updated .

Đầy đủ ví dụ

Kết hợp tất cả lại với nhau, bạn có thể tạo một ví dụ đầy đủ về các quy tắc cho giải pháp lưu trữ hình ảnh:

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

Cơ sở dữ liệu thời gian thực

Cấu trúc cơ bản

Trong Cơ sở dữ liệu thời gian thực, Quy tắc bảo mật Firebase bao gồm các biểu thức giống JavaScript có trong tài liệu JSON.

Họ sử dụng cú pháp sau:

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

Có ba yếu tố cơ bản trong quy tắc:

  • Đường dẫn: Vị trí cơ sở dữ liệu. Điều này phản ánh cấu trúc JSON của cơ sở dữ liệu của bạn.
  • Yêu cầu: Đây là những phương pháp sử dụng các quy tắc để cấp quyền truy cập. Các readwrite quy tắc cấp đọc rộng và truy cập ghi, trong khi validate quy tắc hoạt động như một xác minh thứ để cho phép truy cập dựa trên dữ liệu đến hoặc hiện tại.
  • Tình trạng: Điều kiện cho phép yêu cầu nếu nó trả về true.

Cách các quy tắc áp dụng cho đường dẫn

Trong Cơ sở dữ liệu thời gian thực, Quy tắc áp dụng nguyên tử, có nghĩa là các quy tắc ở các nút mẹ cấp cao hơn ghi đè các quy tắc ở các nút con chi tiết hơn và các quy tắc ở nút sâu hơn không thể cấp quyền truy cập vào đường dẫn mẹ. Bạn không thể tinh chỉnh hoặc thu hồi quyền truy cập tại một đường dẫn sâu hơn trong cấu trúc cơ sở dữ liệu của mình nếu bạn đã cấp nó cho một trong các đường dẫn mẹ.

Hãy xem xét các quy tắc sau:

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

Cấu trúc bảo mật này cho phép /bar/ để được đọc từ bất cứ khi nào /foo/ chứa một đứa trẻ baz với giá trị true . Các ".read": false quy tắc dưới /foo/bar/ không có tác dụng ở đây, vì truy cập không thể bị thu hồi bằng một con đường nhỏ.

Mặc dù nó có vẻ không trực quan ngay lập tức, nhưng đây là một phần mạnh mẽ của ngôn ngữ quy tắc và cho phép thực hiện các đặc quyền truy cập rất phức tạp với nỗ lực tối thiểu. Điều này đặc biệt hữu ích cho an ninh dựa trên người dùng .

Tuy nhiên, .validate quy tắc không thác. Tất cả các quy tắc xác thực phải được thỏa mãn ở tất cả các cấp của hệ thống phân cấp để được phép ghi.

Ngoài ra, vì các quy tắc không áp dụng trở lại đường dẫn chính, hoạt động đọc hoặc ghi không thành công nếu không có quy tắc tại vị trí được yêu cầu hoặc tại vị trí chính cấp quyền truy cập. Ngay cả khi mọi đường dẫn con bị ảnh hưởng đều có thể truy cập được, việc đọc ở vị trí phụ huynh sẽ hoàn toàn thất bại. Hãy xem xét cấu trúc này:

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

Mà không hiểu rằng những quy tắc được đánh giá nguyên tử, nó có vẻ như lấy sự /records/ con đường sẽ trở rec1 nhưng không rec2 . Tuy nhiên, kết quả thực tế là một lỗi:

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
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
}];
Nhanh
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
  });
});
LÊN ĐỈNH
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

Kể từ khi hoạt động đọc tại /records/ là nguyên tử, và không có quy tắc đọc rằng trợ cấp quyền truy cập vào tất cả các dữ liệu dưới /records/ , điều này sẽ ném một PERMISSION_DENIED lỗi. Nếu chúng tôi đánh giá quy tắc này trong trình giả lập an ninh trong chúng ta điều khiển căn cứ hỏa lực , chúng ta có thể thấy rằng các hoạt động đọc đã bị từ chối:

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

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

Các hoạt động đã bị từ chối vì không có quy tắc đọc cho phép truy cập vào /records/ con đường, nhưng lưu ý rằng các quy tắc cho rec1 không bao giờ được đánh giá vì nó không trong đường dẫn chúng tôi yêu cầu. Để lấy rec1 , chúng tôi sẽ cần phải truy cập trực tiếp:

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Nhanh
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
  }
});
LÊN ĐỈNH
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

Biến vị trí

Realtime Quy định cơ sở dữ liệu hỗ trợ $location biến để phù hợp với các đoạn đường. Sử dụng $ prefix trước phân khúc con đường của bạn để phù hợp với quy tắc của bạn cho bất kỳ nút con dọc theo con đường.

  {
    "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')"
          }
        }
      }
    }
  }

Bạn cũng có thể sử dụng $variable song song với tên đường dẫn không đổi.

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