Firebase Firestore Part 1: มาลองใช้ Firestore กัน
Data Structure ของ Firestore และการ Add, Read ข้อมูล
วันนี้เราจะมาลองใช้ Cloud Firestore ของ Firebase กัน ซึ่งที่ชวนมาใช้เนี่ย เพราะว่าปัญหาบางอย่างหลังจากที่ได้ใช้ Realtime Database ที่เอามาเปรียบเทียบกันเพราะทั้ง 2 ตัวนี้เป็น database ของ Firebase เหมือนกัน ซึ่งใน Blog นี้ผมจะเขียนโดยใช้ภาษา Python นะครับ
Get started with Cloud Firestore
จริง ๆ แล้วการใช้งาน Cloud Firestore SDK จะสามารถใช้งานได้ทั้งบน Google Cloud Platform กับ Server ของเรานะครับ แต่ในบทความนี้ ผมจะเลือกการทำบน server ของเราให้ดู
Initial cloud firestore on your own server
ขั้นตอนแรกก่อนที่เราจะไปเริ่มที่ code เราจะไปสร้าง Firebase Project ก่อน เมื่อสร้างแล้วกดไปที่ Project Setting > Service Account > Firebase Admin SDK แล้วเลือก “Generate new private key” เพื่อ download ไฟล์ Admin_SDK.json มา
ชื่อ default ของไฟล์จะเป็นชื่อยาว ๆ จะแก้หรือไม่แก้ก็ได้นะครับ ใน blog นี้ผมจะอิงชื่อ Admin_SDK.json
ต่อไปจะเป็นการ เพิ่ม Firebase Admin SDK ลงใน Python app โดยใช้คำสั่ง pip install -U firebase-admin
แล้วเราก็จะไปเชื่อม firebase กับ app ของเรา ด้วย code นี้
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestorecred = credentials.Certificate('PATH_TO_FILE/Admin_SDK.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
เราใช้ไฟล์ Admin_SDK.json เป็นตัวเชื่อมต่อกับ firebase ทำให้ permission ของ app เราเป็น admin
Adding Data
ตัว Cloud Firestore จะเก็บ data ไว้ใน Document และ Document จะอยู่ภายใต้ Collection อีกต่อนึง เราสามารถลองสร้างข้อมูลได้โดยใช้ code นี้
doc_ref = db.collection(u'users').document(u'BPablo')
doc_ref.set({
u'first': u'Boyce',
u'last': u'Pablo',
u'born': 1996
})
ข้อมูลที่เราสร้างขึ้นมาจะอยู่ใน Collection “users” Document “BPablo” ซึ่งสามารถเข้าไปดูได้ใน Firebase Console ของ Project เราได้เลย
ทีนี้เรามาลองเพิ่ม Document เข้าไปใน Collection “users” ของเรากัน ในครั้งนี้เราจะเพิ่ม key-value ไปอีก 1 ตัว(middle) ที่ไม่ได้ใส่ไปใน Document แรก ซึ่งจะทำให้เราเห็นว่า Collection สามารถมี Document ที่ข้อมูลภายในแตกต่างกันได้
doc_ref = db.collection(u'users').document(u'aturing')
doc_ref.set({
u'first': u'Alan',
u'middle': u'Mathison',
u'last': u'Turing',
u'born': 1912
})
Reading Data
ถ้าต้องการดึงข้อมูลทั้งหมดจาก Collection ลงมาดู ให้อ้างอิงไปที่ Collection และใช้ stream() ในการดึง Document ทั้งหมดลงมา แล้วใช้ loop เพื่อแสดงผลค่าใน Document
users_ref = db.collection(u'users')
docs = users_ref.stream()
for doc in docs:
print(u'{} => {}'.format(doc.id, doc.to_dict()))
ทั้งหมดนี้ก็เป็นเพียงแค่การใช้งานแบบเบื้องต้น ในบทความถัดไปจะมาเล่าถึงความสามารถของ Firestore ที่ Realtime database ไม่มี และมาดูกันว่าชีวิตเราง่ายขึ้นขนาดไหน
ขอแถมเรื่อง Data Structure ของ Firestore ให้ก่อน เผื่อมีโอกาสได้ไปใช้งานจริงก่อนทีผมจะเขียนเรื่องถัดไป 555
Firestore Data Structure
ก่อนอื่นเลยที่เราควรจะรู้คือ การใช้งาน Firestore จะมีการทำ Data Structure ที่แตกต่างกัน ดังนี้
- Documents : วางข้อมูลทั้งหมดลงไปเลย
- Multiple collections : สร้าง Collection ซ้อนแล้วเก็บข้อมูลทั้งชุด
- Subcollections within documents : สร้าง Collection เพื่อแยกประเภทของ Document
สำหรับคนเคยผ่านการเขียนแบบ OOP เราอาจมอง Collection เป็น Package แล้วก็มอง Document เป็น Class ก็ได้
ทีนี้เรามาเปรียบเทียบข้อดีข้อเสียของแต่ละแบบกัน จำเป็นจะต้องออกแบบ Data Structure ให้ดี เวลาที่เรานำไปใช้จะได้ไม่ต้องกลับมาปรับแก้อีกครั้งในภายหลัง
Nested data in documents : Documents
เราสามารถซ้อน array หรือ maps(dict) ภายใน document ได้
ข้อดี : หากข้อมูลของเราไม่ซับซ้อนและคงที่ การเก็บข้อมูลใน document การตั้งค่าและการปรับโครงสร้างแบบนี้จะง่ายที่สุด
ข้อจำกัด : ไม่สามารถ scalable ได้ หากข้อมูลขยายขึ้นตามเวลา และด้วย document ที่ใหญ่ก็จะทำให้ query ช้าลงด้วย
Document BPablo
name :
first : "Boyce"
last : "Pablo"
born : 1996
rooms :
0 : "Software Chat"
1 : "Famous Figures"
2 : "Famous Idols"
Subcollection : Multiple collections
เราสามารถสร้าง collection ภายใน document เมื่อข้อมูลมีการขยายตัวก็ได้
ข้อดี : เมื่อข้อมูลมีขนาดใหญ่ขึ้น document หลักจะไม่เปลี่ยนแปลง แถมการ query ก็ยังทำได้อย่างมีประสิทธิภาพ
ข้อจำกัด : การลบข้อมูลใน subcollection ค่อนข้างยาก
Collection science
Document software
name : "software chat"
Collection users
Document BPablo
first : "Boyce"
last : "Pablo"
Document SLucky
first : "Somsak"
last : "Lucky"
Document astrophysics
...
Root-level collections : Subcollections within documents (แนะนำ)
สร้าง collection ที่ root เพื่อจัดระเบียบข้อมูลที่แตกต่างกัน
ข้อดี : collection ที่ root จะยืดหยุ่น ปรับขยายได้มากที่สุด พร้อมการ query ที่มีประสิทธิภาพในแต่ละ collection
ข้อจำกัด : การรับข้อมูลที่เป็นลำดับขั้น(Hierarchical) อาจซับซ้อนขึ้นเมื่อมีข้อมูลมากขึ้น
Collection users
Document BPablo
first : “Boyce”
last : “Pablo”
born : 1996
Document SLucky
first : “Somsak”
last : “Lucky”
born : 1985
Collection rooms
Document software
Collection messages
Document message1
from : “BPablo”
content : “…”
Document message2
from : “SLucky”
content : “…”