Trước hết, bạn cần phải hiểu được 2 khái niệm cơ bản về Cloud Firestore như sau:
collections
: ứng với CSDL quan hệ thì nó là tablesdocument
: ứng với CSDL quan hệ thì nó là rowfield
: giống với CSDL quan hệ
Chuẩn bị
Có 3 thứ bạn cần chuẩn bị là: danh sách user và 2 collections là posts
và users



Sử dụng Rules Playground
Để hỗ trợ cho việc test các rules được đơn giản và nhanh chóng, và không làm thay đổi đến dữ liệu hiện tại thì chúng ta sẽ sử dụng Rules Playground. Truy cập thông qua https://console.firebase.google.com

Có 3 trường dữ liệu cần lưu ý như sau:
- Simulation type: phương thức request gồm: get, create, update, delete
- Location: đường dẫn tới document hoặc collection cần kiểm tra rule. VD: /posts/BklzUCx35BLnkYs5ru2g
- Authenticated: lựa chọn loại request là đã xác thực hay chưa xác thực

Cài đặt Rules cơ bản
1/ Vô hiệu hóa toàn bộ truy cập vào database
Nghĩa là user không thể thực hiện hành động đọc (read), ghi (write) dữ liệu vào database.
Các khai báo bên dưới được hiểu như sau:
service firebase.storage
: chỉ định rules chỉ được áp dụng cho dịch vụstorage
match /{document=**}
: khai báo này biểu thị rằng toàn bộ rule sẽ được áp dụng cho toàn bộ documentallow read, write: if false
: không cho phép đọc, ghi dữ liệu
rules_version = '2';
service firebase.storage {
match /{document=**} {
allow read, write: if false
}
}
2/ Cho phép bất kì ai đọc và ghi dữ liệu
Chuyển cài đặt if false
sang if true
, có nghĩa là toàn bộ document đều có thể đọc và ghi. Kể cả với những user chưa được xác thực
Cài đặt này chỉ phù hợp khi phát triển hoặc kiểm thử
match /{document=**} {
allow read, write: if true
}
3/ Phân quyền cho user đã đăng nhập
Nếu bạn chỉ muốn cho những user đã đăng nhập được quyền write dữ liệu vào database
match /posts/{postId} {
allow write: if request.auth != null;
}
Lưu ý: user đã đăng nhập ở đây là những user đăng nhập sử dụng Firebase Authentication
4/ Phân quyền cho 1 user cụ thể
Ví dụ, bạn muốn phân quyền ghi dữ liệu trong collection users
cho chính người sở hữu dữ liệu ấy, hay nói cách khác là có uid
trùng với userId
match /users/{userId} {
allow write: if request.auth.uid != userId;
}
5/ Truy cập vào dữ liệu của document
Tiếp theo, bạn có thể tạo ra rule dựa vào dữ liệu trong document bằng cách sử dụng biến resource.data
match /posts/{postId} {
allow read: if resource.data.isDraft == false
}
Biến resource.data
đại diện cho toàn bộ dữ liệu trong document. Giả sử bạn có 1 document như sau
// posts/{postId}
{
name: 'Post no 1';
isDraft: false;
content: "...";
author: "James"
}
Lúc này, bạn có thể sử dụng resource.data.name
, resource.data.content
, .v.v
Cài đặt Rules nâng cao
6/ Sử dụng function để rút gọn rule
Thử hình dung rằng, khi số lượng điều kiện của bạn ngày càng tăng lên và điều kiện cũng phức tạp hơn gây khó khăn trong việc đọc hiểu.
Nếu vẫn sử dụng cách cài đặt điều kiện như trên thì không tốt chút nào. Để giải quyết vấn đề này, chúng ta sẽ sử dụng function
match /posts/{postId} {
function isSignedIn() { // tạo function
return request.auth != null;
}
allow read: if isSignedIn(); // gọi function - khá giống javascript
}
Trông ngắn gọn và tường minh hơn đúng k 🌝
7/ Truy cập đến dữ liệu từ collection khác
Trường hợp tiếp theo, nếu bạn muốn truy cập đến dữ liệu từ 1 collection khác thì sao. Xem xét ví dụ: chỉ cho phép tác giả hoặc admin sửa hoặc xóa bài viết của họ tạo ra
match /post/{postId} {
allow update, delete: if isAuthor() || isAdmin();
function isAuthor() {
return resource.data.ownerId == request.auth.uid;
}
function isAdmin() {
return get(/databases/$(database)/documents/
user/$(request.auth.uid)).data.role == "ADMIN";
}
}
Hàm get()
được sử dụng để giải quyết trường hợp này. Ở ví dụ trên, hàm này được giải thích như sau:
- get : sử dụng để truy xuất các collection khác
- /databases/$(database)/documents/user/$(request.auth.uid): đường dẫn đến document thuộc collection cần lấy dữ liệu.
- get(</path/to/document>).data: chứa kết quả trả về của hàm get
8/ Kiểm tra dữ liệu có tồn tại hay không
Muốn kiểm tra xem 1 document có tồn tại hay không thì sử dụng hàm exists
, các sử dụng khá đơn giản như dưới
exists(/databases/$(database)/documents/collectionName/$(documentId))
9/ Phân quyền theo nhiều cấp dữ liệu
Cuối cùng, bạn còn có thể phân quyền cho từng document bên trong collection
match /databases/{database}/documents {
match /post/{postId} {
allow read, write: if <condition>;
match /children {
allow read: if <condition>;
}
}
}
Tài liệu tham khảo
Nếu bạn cần tham khảo thêm về các method khác ngoài write
, read
thì có thể tham khảo 1 số nguồn dưới đây
Tài liệu về ngôn ngữ được sử dụng để cài đặt Rules
https://firebase.google.com/docs/rules/rules-languageNhững câu lệnh cài đặt Rules cơ bản
https://firebase.google.com/docs/rules/basics
Kết
Với 9 cài đặt trên, hi vọng các bạn có thể nắm được những quy tắc cơ bản khi cài đặt rules cho Cloud Firestore.
Nguồn tham khảo:
https://khreniak.medium.com/cloud-firestore-security-rules-basics-fac6b6bea18e
https://firebase.google.com/docs/rules