Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

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 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 gửi đến.

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

Cửa hàng lửa trên đá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 để 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 thức thuận tiện readwrite 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 thị dưới dạng đường dẫn URI.
  • Quy tắc: Câu lệnh allow , bao gồm một điều kiện cho phép một yêu cầu nếu nó được đánh giá là đúng.

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ó. Phiên bản 2 của 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 định sử dụng truy vấn nhóm bộ sưu tập . Bạn phải chọn tham gia phiên bản 2 bằng cách tạo 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 {

đường dẫn 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 khớp 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 đã 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 đối sánh được đánh giá, biến city sẽ phân giải thành tên tài liệu thành phố, chẳng hạn như SF hoặc NYC .

Bộ sưu tập con phù hợp

Dữ liệu trong Cloud Firestore được tổ chức 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.

Xem xét tình huống trong đó mỗi tài liệu trong bộ sưu tập cities chứa một bộ sưu tập con các landmarks . Các quy tắc bảo mật chỉ áp dụng tại đường dẫn phù hợp, do đó, các điều khiển 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 con các 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 match , đường dẫn của câu lệnh match bên trong luôn liên quan đến đường dẫn của câu lệnh 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>;
    }
  }
}

Ký tự đại diện đệ quy

Nếu bạn muốn các quy tắc áp dụng cho một 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 tập hợp con được lồng 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ạ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 hành vi 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

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, do đó, match /cities/{city}/{document=**} khớp với các tài liệu trong bộ sưu tập con nhưng không khớp trong bộ sưu tập các cities , trong khi match /cities/{document=**} khớp với cả hai tài liệu trong bộ sưu tập bộ sưu tập cities và bộ sưu tập con.

Các ký tự đại diện đệ quy phải xuất hiện ở 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 0 hoặc nhiều mục đường dẫn. match/cities/{city}/{document=**} khớp với 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 .

Báo cáo đối sánh chồng chéo

Một tài liệu có thể khớp nhiều hơn một câu lệnh match . Trong trường hợp có nhiều biểu thức allow khớp với một yêu cầu, quyền truy cập được 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 cho 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 tài liệu đơn và yêu cầu truy vấn.
  • 20 để đọc, giao dịch và ghi nhiều tài liệu. Giới hạn trước đó là 10 cũng áp dụng cho từng hoạt động.

    Ví dụ: hãy tưởng tượng bạn tạo một yêu cầu ghi theo đợ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 và yêu cầu ghi theo lô sử dụng 6 trong số 20 lệnh gọi truy cập.

Vượt quá một trong hai giới hạn sẽ dẫn đến lỗi quyền bị từ chối.

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 đ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ố đối số hàm tối đa 7
Số liên kết biến let tối đa trên mỗi hàm 10
Số lần gọi hàm đệ quy hoặc theo chu kỳ tối đa 0 (không được phép)
Số 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 đối với 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 bằng firebase deploy .
  • giới hạn 250 KB đối với 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 ở mặt sau.

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 để 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 thức thuận tiện readwrite 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 thị dưới dạng đường dẫn URI.
  • Quy tắc: Câu lệnh allow , bao gồm một điều kiện cho phép một yêu cầu nếu nó được đánh giá là đúng.

đường dẫn phù hợp

Quy tắc bảo mật lưu trữ đám mây match đường dẫn tệp được sử dụng để truy cập tệp trong Lưu trữ đám mây. Các quy tắc có thể match các đườ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 đánh giá là false , yêu cầu sẽ bị từ chối.

trận đấu 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>;
  }
}

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 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, chẳng hạn như profilePhoto.png hoặc nhiều phân đoạn đường dẫn, chẳng hạn như images/profilePhoto.png .

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, chẳng hạn như {string} . Có thể khai báo ký tự đại diện nhiều đoạn 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, thì kết quả là OR của kết quả đánh giá tất cả các quy tắc. Nghĩa là, nếu bất kỳ quy tắc nào mà tệp khớp với giá trị là true , thì kết quả là true .

Trong các quy tắc trên, tệp "images/profilePhoto.png" có thể được đọc nếu condition hoặc other_condition đánh giá là đúng, trong khi tệp "images/users/user:12345/profilePhoto.png" chỉ 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ừ 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à 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 tới 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 gian nhận được yêu cầu và giá trị resource mới nếu yêu cầu là 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à tải trọng 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 Sự miêu tả
auth bản đồ<chuỗi, chuỗi> 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 đồ các xác nhận quyền sở hữu JWT của Firebase Authentication. Nếu không, nó sẽ là null .
params bản đồ<chuỗi, chuỗi> Bản đồ chứa các tham số truy vấn của yêu cầu.
path đường dẫn path đại diện cho đường dẫn mà yêu cầu đang được thực hiện.
resource bản đồ<chuỗi, chuỗi> Giá trị tài nguyên mới, chỉ xuất hiện trên các yêu cầu write .
time dấu thời gian Dấu thời gian biểu thị thời gian máy chủ 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 tải lên các tệp có loại nội dung nhất định hoặc chỉ xóa các tệp có kích thước lớn hơn một kích thước nhất định.

Quy tắc bảo mật 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 xuất hiện trong đối tượng Lưu trữ đám mây. Các thuộc tính này có thể được kiểm tra theo yêu cầu read hoặc write để đảm bảo tính toàn vẹn của dữ liệu.

Đối với các 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ó khả năng 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 của ứng dụng chẳng hạn 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 Sự miêu tả
name chuỗi Tên đầy đủ của đối tượng
bucket chuỗi Tên của vùng chứa đối tượng này.
generation int Quá trình tạo đối tượng Google Cloud Storage của đối tượng này.
metageneration int Siêu dữ liệu đố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 chuỗi Hàm băm MD5 của đối tượng.
crc32c chuỗi Hàm băm crc32c của đối tượng.
etag chuỗi etag được liên kết với đối tượng này.
contentDisposition chuỗi Bố cục nội dung được liên kết với đối tượng này.
contentEncoding chuỗi Mã hóa nội dung được liên kết với đối tượng này.
contentLanguage chuỗi Ngôn ngữ nội dung được liên kết với đối tượng này.
contentType chuỗi Loại nội dung được liên kết với đối tượng này.
metadata bản đồ<chuỗi, chuỗi> 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ừ generation , siêu dữ timeCreated etag metageneration 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ần 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à yêu cầu truy vấn.

Vượt quá giới hạn này dẫn đến lỗi quyền bị từ chối.

Các cuộc gọi truy cập vào 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.

Ví dụ đầy đủ

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 như 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 thức 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ó được đánh giá là đúng.

Cách 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ử, nghĩa là các quy tắc ở các nút gốc cấp cao hơn sẽ 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 gốc. Bạn không thể tinh chỉnh hoặc thu hồi quyền truy cập ở đườ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 quyền truy cập đó cho một trong các đường dẫn chính.

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 bất cứ khi nào /foo/ chứa một baz con có giá trị true . Quy tắc ".read": false trong /foo/bar/ không có hiệu lực ở đây, vì đường dẫn con không thể thu hồi quyền truy cập.

Mặc dù 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, quy tắc .validate không xếp 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 để cho phép ghi.

Ngoài ra, do các quy tắc không áp dụng ngược lại cho đường dẫn gốc nên 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í gốc 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, thì việc đọc tại vị trí gốc sẽ thất bại hoàn toàn. 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ó vẻ như việc tìm nạp đường dẫn /records/ 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
});
Mục tiêu-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
  });
});
CÒN LẠI
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 chúng tôi đánh giá quy tắc này trong trình giả lập bảo mật trong bảng điều khiển Firebase của mình, 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 đường dẫn /records/ , nhưng lưu ý rằng quy tắc cho rec1 chưa bao giờ được đánh giá vì nó không nằm trong đường dẫn chúng tôi yêu cầu. Để tìm nạp rec1 , chúng ta 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
});
Mục tiêu-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
  }
});
CÒN LẠI
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 đoạn đường dẫn. Sử dụng tiền tố $ phía trước đoạn đường dẫn của bạn để khớp 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 cố định.

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