Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

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

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

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, 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: Phương thức hoặc các phương thức được gọi trong câu lệnh allow . Đâ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 , updatedelete . Các phương pháp readwrite thuận tiện cho phép truy cập đọc và ghi rộng rãi trên cơ sở dữ liệu hoặc đường dẫn lưu trữ được chỉ định.
  • Đường dẫn: Cơ sở dữ liệu hoặc vị trí lưu trữ, được biểu diễn dưới dạng đường dẫn URI.
  • Quy tắc: Câu lệnh allow , bao gồm điều kiện cho phép một yêu cầu nếu nó đánh giá là 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 quy tắc thay đổi hoạt động 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 định sử dụng truy vấn nhóm thu thập . Bạn phải chọn tham gia phiên bản 2 bằng cách thực hiện 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. Câu lệnh đối sánh 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 nào trong đường dẫn được chỉ định, như trong match /cities/{city} .

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

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

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 tình huống mà mỗi tài liệu trong bộ sưu tập cities có chứa một bộ sưu tập phụ các landmarks . Các quy tắc bảo mật chỉ áp dụng tại con đường phù hợp, do đó, các kiểm soát truy cập được xác định trên bộ sưu tập cities không áp dụng cho bộ sưu tập phụ của landmarks . 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ồng các câu lệnh so match , đường dẫn của câu lệnh so match bên trong luôn liên quan đến đường dẫn của câu lệnh so match bên ngoài. Do đó, các bộ quy tắc sau đây 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 các quy tắc áp dụng cho hệ thống phân cấp sâu tùy ý, hãy sử dụng cú pháp ký tự đại diện đệ 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 được liệt kê ở trên sẽ khớp với một tài liệu được đặt tại /cities/SF/landmarks/coit_tower và giá trị của biến document sẽ là 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. Chúng không khớp với một đường dẫn trống, vì vậy match /cities/{city}/{document=**} khớp với tài liệu trong bộ sưu tập con nhưng không khớp với bộ sưu tập cities , trong khi match /cities/{document=**} khớp với cả hai tài liệu trong bộ sưu tập cities và bộ sưu tập phụ.

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=**} khớp các tài liệu trong bất kỳ bộ sưu tập con nào cũng như các tài liệu trong bộ sưu tập cities .

Bạn phải chọn tham gia 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 truy vấn nhóm bộ sưu tập , bạn phải sử dụng phiên bản 2, xem bảo mật truy vấn nhóm bộ sưu tập .

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

Có thể một tài liệu khớp với nhiều hơn một câu lệnh match . Trong trường hợp nhiều biểu thức allow khớp với một yêu cầu, quyền truy cập được cho phép nếu bất kỳ điều kiện nào 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ác lần đọc và ghi vào bộ sưu tập cities sẽ được phép vì quy tắc thứ hai luôn true , mặc dù quy tắc đầu tiê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 lệnh gọi exists() , get()getAfter() tối đa cho mỗi 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.

Độ sâu câu lệnh match lồng nhau tối đa 10
Độ dài đường dẫn tối đa, trong các phân đoạn đường dẫn, được phép trong một tập hợp các câu lệnh so match lồng nhau 100
Số lượng biến nắm bắt đường dẫn tối đa được phép trong một tập hợp các câu lệnh so match lồng nhau 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 các ràng buộc biến let mỗi hàm 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:
  • giới hạn 256 KB về kích thước của nguồn văn bản bộ quy tắc được xuất bản từ bảng điều khiển Firebase hoặc từ CLI sử dụ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: Phương thức hoặc các phương thức được gọi trong câu lệnh allow . Đâ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 , updatedelete . Các phương pháp readwrite thuận tiện cho phép truy cập đọc và ghi rộng rãi trên cơ sở dữ liệu hoặc đường dẫn lưu trữ được chỉ định.
  • Đường dẫn: Cơ sở dữ liệu hoặc vị trí lưu trữ, được biểu diễn dưới dạng đường dẫn URI.
  • Quy tắc: Câu lệnh allow , bao gồm điều kiện cho phép một yêu cầu nếu nó đánh giá là true.

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

Quy tắc bảo mật lưu trữ đám mây match các đường dẫn tệp được sử dụng để truy cập tệp trong Bộ nhớ đám mây. Các quy tắc có thể match đường dẫn chính xác hoặc đường dẫn ký tự đại diện và các quy tắc cũng có thể được lồng vào nhau. Nếu không có quy tắc đối sánh nào cho phép một phương thức yêu cầu hoặc điều kiện được đánh giá là false , thì yêu cầu sẽ 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 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

Các quy tắc cũng có thể được sử dụng để match một mẫu bằng cách sử dụng các ký tự đại diện. Ký tự đại diện là một biến được đặt tên đại diện cho một chuỗi đơn như profilePhoto.png hoặc nhiều đoạn đường dẫn, chẳng hạn như images/profilePhoto.png .

Một ký tự đại diện được tạo 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 ký tự đại diện nhiều đoạn có thể được khai báo bằng cách thêm =** vào 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 nhiều quy tắc khớp với một tệp, kết quả là OR của kết quả của tất cả các đánh giá quy tắc. Nghĩa là, nếu bất kỳ quy tắc nào mà tệp phù hợp được đánh giá true , thì kết quả là true .

Trong các quy tắc ở trên, tệp "images / other_condition " có thể được đọc nếu condition hoặc điều kiện khác đánh giá thành true, trong khi tệp "hình ảnh / người dùng / người dùng: 12345 / other_condition " chỉ tuân theo kết quả của điều kiện khác .

Một biến ký tự đại diện có thể được tham chiếu từ trong match , cung cấp tên tệp hoặc ủy 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à các 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á

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

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

Dưới đây là danh sách đầy đủ các thuộc tính trong đối tượng request :

Tài sản Loại hình Sự mô tả
auth map <string, string> Khi người dùng đăng nhập, hãy cung cấp uid , ID duy nhất của người dùng và token , bản đồ xác thực Firebase JWT. Nếu không, nó sẽ là null .
params map <string, string> Bản đồ chứa các tham số truy vấn của yêu cầu.
path đường dẫn Một path đại diện cho đường dẫn mà yêu cầu đang được thực hiện.
resource map <string, string> Giá trị tài nguyên mới, chỉ hiển thị khi yêu cầu write .
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.

Quy tắc bảo mật của Firebase cho Lưu trữ đám mây cung cấp siêu dữ liệu tệp trong đối tượng resource , chứa các cặp khóa / giá trị của siêu dữ liệu hiển thị trong đối tượng Lưu trữ đám mây. Các thuộc tính này có thể được kiểm tra trên các yêu cầu read hoặc write để đảm bảo tính toàn vẹn của dữ liệu.

Khi yêu cầu write (chẳng hạn như tải lên, cập nhật siêu dữ liệu và xóa), ngoài đối tượng resource , chứa siêu dữ liệu tệp cho tệp hiện đang tồn tại ở đường dẫn yêu cầu, bạn cũng có thể sử dụng đối tượng request.resource , 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.

Dưới đây là danh sách đầy đủ các thuộc tính trong đối tượng resource :

Tài sản Loại hình Sự mô tả
name sợi dây Tên đầy đủ của đối tượng
bucket sợi dây Tên của thùng chứa đối tượng này.
generation int Việc tạo đối tượng Google Cloud Storage của đối tượng này.
metageneration int Việc kiểm soát đối tượng Google Cloud Storage của đối tượng này.
size int 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 biểu thị thời gian một đối tượng được cập nhật lần cuối.
md5Hash sợi dây Một băm MD5 của đối tượng.
crc32c sợi dây Một hàm băm crc32c của đối tượng.
etag sợi dây Etag liên kết với đối tượng này.
contentDisposition sợi dây Sự bố trí nội dung liên quan đến đối tượng này.
contentEncoding sợi dây Mã hóa nội dung được liên kết với đối tượng này.
contentLanguage sợi dây Ngôn ngữ nội dung liên quan đến đối tượng này.
contentType sợi 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 thứ này, ngoại trừ phần generation , đo etag metageneration timeCreated được tạo và updated .

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 lệnh gọi firestore.exists()firestore.get() tối đa cho mỗi yêu cầu

2 cho các yêu cầu tài liệu đơn và các yêu cầu truy vấn.

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

Các cuộc gọi truy cập đến cùng một 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.

Đầ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à các phương pháp mà quy tắc sử dụng để cấp quyền truy cập. Các quy tắc readwrite cấp quyền truy cập đọc và ghi rộng rãi, trong khi các quy tắc validate hoạt động như một xác minh thứ cấp để cấp quyền truy cập dựa trên dữ liệu đến hoặc dữ liệu hiện có.
  • Điều kiện: Điều kiện cho phép một yêu cầu nếu nó đánh giá là 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 ở 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 đọc /bar/ từ bất cứ khi nào /foo/ chứa baz con với giá trị true . Quy tắc ".read": false dưới /foo/bar/ không có hiệu lực ở đây, vì không thể thu hồi quyền truy cập bằng đường dẫn con.

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 bảo mật dựa trên người dùng .

Tuy nhiên, các quy tắc .validate không phân tầng. 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, bởi vì các quy tắc không áp dụng trở lại đường dẫn chính, thao tác đọ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 tại 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
      }
    }
  }
}

Nếu không hiểu rằng các quy tắc được đánh giá nguyên tử, có thể có vẻ như việc tìm nạp /records/ path sẽ trả về rec1 chứ không phải 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
Lưu ý: Sản phẩm Firebase này không khả dụng trên mục tiêu Clip ứng dụng.
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
Lưu ý: Sản phẩm Firebase này không khả dụng trên mục tiêu Clip ứng dụng.
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

Vì thao tác đọc tại /records/ là nguyên tử và không có quy tắc đọc nào cấp quyền truy cập vào tất cả dữ liệu trong /records/ , điều này sẽ gây ra lỗi PERMISSION_DENIED . Nếu đánh giá quy tắc này trong trình mô phỏng bảo mật trong bảng điều khiển Firebase , chúng tôi có thể thấy rằng thao tác đọc đã bị từ chối:

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

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

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

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
Lưu ý: Sản phẩm Firebase này không khả dụng trên mục tiêu Clip ứng dụng.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Nhanh
Lưu ý: Sản phẩm Firebase này không khả dụng trên mục tiêu Clip ứng dụng.
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í

Quy tắc cơ sở dữ liệu thời gian thực hỗ trợ biến $location để khớp với các phân đoạn đường dẫn. Sử dụng tiền tố $ ở phía trước đoạn đường dẫn của bạn để đối sánh quy tắc của bạn với bất kỳ nút con nào dọc theo đường dẫn.

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