ใส่ Firestore rule
Firestore Security Rule คืออะไร ?
เอกสารต้นฉบับ: https://firebase.google.com/docs/firestore/security/get-started
Firestore Security Rule คือ set ของ configurations ที่ระบุเอาไว้ว่าใครที่สามารถอ่านและเขียนข้อมูลลงได้บ้าง
- ฉบับ local (หรือ development บนเครื่อง) จะสามารถแก้ผ่าน
firestore.rules
ที่สร้า งจากfirebase init
ตรงๆได้ - ฉบับ server จะสามารถแก้ผ่านหน้าเว็บ Firebase > Firestore > Rules
ในหัวข้อนี้เราจะปรับกันที่ local กันก่อน แล้วเดี๋ยวก่อน deployment เราจะทำการย้าย Firestore Security Rule อีกที
กั้นข้อมูล user
โดย เงื่อนไขคือ
- ดึงได้เฉพาะข้อมูลของ user ตัวเอง (ถ้าไม่ใช่ admin)
- ไม่เว้นแม้แต่ moderator ก็มาเห็น user คนอื่นไม่ได้ (เมื่อลองมาเปิด path ตรงๆ)
- ถ้าเป็น admin = สามารถดูข้อมูลทุกคนได้
ที่ firestore.rules
service cloud.firestore {
match /databases/{database}/documents {
function isAdmin() {
return request.auth.uid != null || get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
}
match /users/{userId} {
allow read, write: if request.auth != null && (request.auth.uid == userId || isAdmin());
}
}
}
กั้นข้อมูล Frontend ให้เห็นแค่ status 'open' เท่านั้น
เพิ่มเงื่อนไขนี้เข้ามาใน firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /products/{productId} {
allow read: if (request.auth != null && isAdmin()) || (resource.data.status == 'open');
allow write: if (request.auth != null && isAdmin()) || (resource.data.status == 'open');
}
}
}
ทีนี้เราจะเจอว่าหน้าบ้านไม่สามารถเรียกใช้ข้อมูลได้ ให้ปรับการเรียก product ฝั่ง Frontend ใหม่เป็น
ที่ stores/user/product.js
import { defineStore } from 'pinia'
import {
collection,
getDocs,
// เพิ่ม query กับ where เข้ามา
query,
where
} from 'firebase/firestore'
export const useUserProductStore = defineStore('user-product', {
state: () => ({
list: [],
loaded: false,
page: 1,
limit: 2
}),
actions: {
async loadProduct () {
// เพิ่ม where และ query ในการเรียก condition ตาม rule
const productsCol = query(collection(db, 'products'), where('status', '==', 'open'))
const productSnapshop = await getDocs(productsCol)
const productList = productSnapshop.docs.map(doc => doc.data())
if (productList && productList.length > 0) {
this.list = productList
}
this.loaded = true
},
/* function อื่นเหมือนเดิม */
}
})
ผลลัพธ์ของ code นี้ ให้ลอง setup product เป็น status close ดู = จะเจอว่า product ที่เป็น close จะไม่แสดงออกมาได ้