Chúng ta sẽ tiếp tục series về Firestore, nếu 2 bài trước thì chúng ta đã biết cách set security rule, giờ để xem ảnh hưởng của rule này lên lúc query data
Khi write và read documents, để tiết kiệm thời gian và resource, Cloud Firestore đánh giá các kết quả có thể xảy ra chứ không chạy qua tất cả giá trị. Nếu câu query có document mà user không có quyền truy cập, toàn bộ cái request sẽ fail
Lưu ý: cách chạy này chỉ áp dụng khi query nhiều documents từ 1 collection. Khi bạn dùng ID để truy xuất đến 1 document sẽ không giống như trên.
auth.uid
Query doucment dựa trên Ví dụ bên dưới mô ta cách viết câu query để lấy documents. Hình dung database bao gồm 1 collection của documents story
/stories/{storyid}
{
title: "A Great Story",
content: "Once upon a time...",
author: "some_auth_id",
published: false
}
Security rule trên story
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Chỉ user đăng nhập có id = author
allow read, write: if request.auth.uid == resource.data.author;
}
}
}
Câu query nếu sẽ fail vì nó không khớp với security rules ở trên, mặc dù user đăng nhập chính là author của 1 document trong collection
db.collection('stories').get()
Trường hợp này chúng ta phải viết như sau
var user = firebase.auth().currentUser;
db.collection('stories').where('author', '==', user.uid).get()
Query document dựa trên field
Để hình dung tương quan giữa rule và lúc query, xét ví dụ rule bên dưới, collection stories cho phép bất kỳ user nào truy cập vào story documents khi giá trị của field published là true
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
allow read: if resource.data.published == true || request.auth.uid == resource.data.author
allow write: if request.auth.uid == resource.data.author;
}
}
}
Để query data ở trên
db.collection('stories').where('published', '==', true).get()
Tính toán ràng buộc lúc query
Trong biến request.query
bao gồm limit
, offset
, và orderBy
, ví dụ chúng ta đặt ra rule là không trả về dữ liệu nếu câu query không chứa limit hoặc limit lớn hơn quy định
allow list: if request.query.limit <= 10
Một cách đầy đủ hơn, gom các điều kiện về author và publish vào trong hàm authorOrPublished()
để tránh lập lại
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// `true` nếu story đang 'published'
// hoặc authored = người đang request
function authorOrPublished() {
return resource.data.published == true || request.auth.uid == resource.data.author;
}
allow list: if request.query.limit <= 10 &&
authorOrPublished();
allow get: if authorOrPublished();
allow write: if request.auth.uid == resource.data.author;
}
}
}
Initializing...