Codding Gun

Cloud Firestore คืออะไร?

Cloud Firestore เป็น Database as a Service(DaaS) คือเราสามารถสร้าง database server ขึ้นมาใช้งานได้โดยที่เราไม่ต้องดูแล infrastructure

ซึ่งมีคุณสมบัติของ Cloud Firestore มีดังนี้

Firebase vs Firestore

เป็น 2 คำที่มีความสับสนอยู่พอสมควร Firebase เป็น platform ที่ให้บริการ realtime database และมี services อื่นๆให้เลือกใช้อีกมากมายอย่างที่เราเห็นมาก่อนหน้านี้ ซึ่งหนึ่งในนั้นคือ Firestore ซึ่งทำหน้าที่เป็น database server อย่างเดียว ซึ่งถ้าจะเปรียบเทียบระหว่าง database ด้วยกัน ต้องเป็น Firestore และ Realtime Database

Firestore vs Realtime Database

ใน Firebase จะมี database ให้เราเลือกอยู่ 2 ตัวตือ Firestore และ Realtime Database ซึ่งทั้ง 2 ตัวนี้จะมีความแตกต่างกันดังนี้

Firestore Data Model

โครงสร้างการจัดเก็บข้อมูลของ Firestore จะเป็นแบบ document-oriented database ซึ่งจะเก็บข้อมูลเป็นลำดับชั้น(hierarchy) โดยจะแบ่งเป็น

  1. Document การจัดเก็บ data ของ Firestore จะอยู่ในรูปของ JSON เรียกว่า document แบบนี้

    {
        "firstname": "John",
        "lastname": "Doe",
        "born": 1979
    }
    

    Document จะเปรียบได้กับ record ใน Relational Database

  2. Collection หลังจากนั้น Document ประเภทเดียวกันจะถูกวางไว้ใน Collection เดียวกัน

    users = [
        { "firstname": "John", "lastname": "Doe", "born": 1979},
        { "firstname": "Jenny", "lastname": "Doe", "born": 1982}
    ]
    

    Collection จะเทียบได้กับ table ใน Relational Database

  3. Database ใน level นี้จะเหมือนกับ relational database เลยคือนำ Collections ต่างๆมารวมกันอยู่ใน database ตัวเดียวกัน ความสัมพันธ์ของ data, document และ collection จะเป็นดังรูป

Firestore Data Model
Firestore data model

ราคาของ Cloud Firestore

เราสามารถใช้งาน Cloud Firestore ได้ฟรีโดยมีข้อจำกัดดังนี้

วิธีจัดการกับ Firebase

การทำงานกับ services ต่างๆของ Firebase นั้นทำได้ 2 ทางด้วยกันคือ

  1. Firebase Console การทำงานกับ Firebase Console คือการเข้าไปทำงานผ่าน Web UI ซึ่งสามารถเข้าไปจัดการกับ Firebase ได้ที่ https://console.firebase.google.com
  2. Firebase CLI เมื่อเราต้องมีการทำงานที่เป็นอัตโนมัติมากขึ้นเราต้องใช้ Firebase CLI ซึ่ง Firebase CLI เป็น command line ที่ช่วยให้เราจัดการกับ services ต่างๆบน Firebase ได้โดยที่ไม่ต้องใช้คน งานที่เราต้องนำ Firebase CLI มาใช้ ส่วนใหญ่เป็นการทำ Automated Deploy ใน CI/CD pipeline

สร้าง Firestore database

การสร้าง database ใน Firestore มีดังนี้

  1. เข้าไปที่ Firebase Console เพื่อสร้าง Project ขึ้นมาใหม่

    Create new firebase project
    ตั้งชื่อ Project ให้กับ Firebase
    Create new firebase project
    Enable Google Analytics
    Create new firebase project
    เลือก Account ของ Google Analytics

    หลังจากนั้นเราจะเข้าสู่หน้า console ซึ่งจะมี services ต่างของ firebase ให้เราเลือกใช้บริการ

    Firebase console

  2. เข้าไปที่ menu Firestore Database ด้านซ้ายมือ

    Firebase database services

    เลือก Create Database หลังจากนั้นจะมี pop-up ขึ้นมาให้เราตั้งค่า Database

    Firestore create database

    ใน step นี้ Firestore จะให้เราระบุ Location ของ Database

    Firestore set locatoion

    ใน step ถัดไป Firestore จะให้เราเลือก security rules

    Firestore multi-regions

    เราสามารถเลือก security rules ได้ 2 แบบคือ

    • Production mode สำหรับการใช้งานบน production จริง data จะเป็น provate โดย default
    • Testing mode สำหรับการทดสอบบน development phase data จะเป็น public สามารถใช้งานได้แค่ 30 วัน

    หลังจากนั้นก็จะเข้าสู่หน้า console หลักสำหรับจัดการกับ database

    Firestore database console

  3. สร้าง collection โดยการคลิกที่ Start Collection

    Firestore create collection

    ระบุชื่อ field และกำหนด data type ให้กับแต่ละ field หลังจากนั้นกด Save ก็จะกลับเข้าสู่หน้า console ของ Firestore database ดังรูป

    Firestore console

Firestore Data Types

เราสามารถกำหนด data type เหล่านี้ให้กับ field ใน document ของเราได้

Datatype
Description
Text String เก็บข้อมูลเป็นข้อความ
Array เก็บเป็น collection ของข้อมูล เช่น [1,2,3]
Boolean เก็บเป็น True หรือ False
Bytes เก็บข้อมูลเป็น Blob(ขนาดสูงสุด 1 MiB) โดยที่ี Firestore จะใช้ 1500 bytes แรกในการ query
Date and time เก็บวันที่และเวลา
Floating-point number เก็บเลขทศนิยม ใช้พื้นที่ขนาด 64 bits
Integer เก็บเลขจำนวนเต็ม
Map เก็บข้อมูลเป็นแบบ Key-Value เช่น { a : 10, b : 20 }
NaN หรือ Null คือ ค่าว่าง
Reference เก็บ ID ที่ชี้ไปยัง document อื่นๆโดยมีรูปแบบเป็น projects/[PROJECT_ID]/databases/[DATABASE_ID]/documents/[DOCUMENT_PATH]

การ Query ข้อมูลใน Firestore

การใช้งานฐานข้อมูลใดๆก็ตามเราต้องรู้วิธีการ query ข้อมูล แต่ก่อนที่เราจะเขียน query สิ่งแรกที่เราต้องทำคือ

  1. ติดตั้ง firebase sdk

    $ npm i --save firebase
    
  2. import firestore module เข้าไปก่อน

    import { initializeApp } from 'firebase/app';
    import { getFirestore, collection, getDocs, query, where } from 'firebase/firestore';
    
  3. Setup configuratin

    const firebaseConfig = {
        apiKey: 'FIREBASE API KEY',
        authDomain: 'FIREBASE AUTH DOMAIN',
        projectId: 'CLOUD FIRESTORE PROJECT ID'
    };
    
    const app = initializeApp(firebaseConfig);
    const db = getFirestore(app);
    

รูปแบบของกาาร query ข้อมูลใน Firestore จะมีดังนี้

การ Query ข้อมูลใน Firestore

เราสามารถทำการ query ข้อมูลออกมาจาก collection ชื่อ users ได้ด้วยคำสั่ง

1
2
3
4
5
6
async function getCities(db) {
  const usersRef = collection(db, 'users');
  const userSnapshot = await getDocs(usersRef);
  const userList = userSnapshot.docs.map(doc => doc.data());
  return userList;
}

การ Query เอา document ออกมาเราจะได้สิ่งที่เรียกว่า DocumentSanpshot(บรรทัดที่ 3) ซึ่งเป็น meta-data ที่อธิบายว่าจะไปเอา document ID ไหน ซึ่งในชั้นตอนนี้เราจะยังไม่ได้ data ออกมาจริงๆ หลังจากนี้เราต้องเอา DocumentSanpshot ไปดึงข้อมูลออกไปใช้งาน ในบรรทัดที่ 4 และ 5

ทำไมต้องมี DocumentSnapshot?

ที่เราต้องมี Snapshot เพราะเราต้องการข้อมูลที่เป็น realtime ดังนั้นเราต้องการรับรู้การเปลี่ยนแปลง(listener)ของ database

ถ้าจะใส่เงื่อนไขเข้าไปเราจะแทรก function where เข้าไปแบบนี้

1
2
3
4
5
6
7
async function getCities(db) {
  const usersRef = collection(db, 'users');
  const q = query(userRef, where("born", ">", 1980));
  const userSnapshot = await getDocs(q);
  const userList = userSnapshot.docs.map(doc => doc.data());
  return userList;
}

สิ่งที่ได้จาก function where คือ QuerySnapshot ไม่ใช่ DocumentSnapshot แบบตัวอย่างก่อนหน้านี้ ซึ่ง method ของทั้ง 2 ตัวนี้แตกต่างกัน เช่น

และถ้าต้องการจัดเรียงข้อมูลเราจะใช้ function orderBy แบบนี้

1
2
3
4
5
6
7
async function getCities(db) {
  const usersRef = collection(db, 'users');
  const q = query(usersRef, orderBy("state", "desc"));
  const querySnapshot = await getDocs(q);
  const userList = userSnapshot.docs.map(doc => doc.data());
  return userList;
}
Phanupong Permpimol
Follow me