ไม่มีชื่อบทความ
🔍 Query ขั้นสูง: Pagination, Filtering, และ Composite Index
📄 เป้าหมาย: ทำปุ่ม “โหลดเพิ่ม” พร้อมค้นหาด้วยเงื่อนไข
- แสดงเอกสารล่าสุดแบบ page ละ 10 รายการ
- กรองเฉพาะ
status = "approved" - เรียงตาม
createdAtแบบใหม่สุดก่อน - มีปุ่ม "โหลดเพิ่ม" เพื่อดึงหน้าถัดไป
📦 ตัวอย่างโค้ด: ดึงข้อมูลหน้าแรก + โหลดเพิ่ม
'use client';
import { useState, useEffect } from 'react';
import { db } from '@/lib/firebaseClient';
import {
collection,
query,
where,
orderBy,
limit,
getDocs,
startAfter
} from 'firebase/firestore';
export default function PaginatedList() {
const [items, setItems] = useState([]);
const [lastDoc, setLastDoc] = useState(null);
const loadData = async () => {
const baseQuery = query(
collection(db, 'posts'),
where('status', '==', 'approved'),
orderBy('createdAt', 'desc'),
limit(10),
...(lastDoc ? [startAfter(lastDoc)] : [])
);
const snap = await getDocs(baseQuery);
const newItems = snap.docs.map(doc => ({ id: doc.id, ...doc.data() }));
setItems(prev => [...prev, ...newItems]);
setLastDoc(snap.docs[snap.docs.length - 1]);
};
useEffect(() => {
loadData();
}, []);
return (
<div>
<ul>
{items.map(item => <li key={item.id}>{item.title}</li>)}
</ul>
<button onClick={loadData}>โหลดเพิ่ม</button>
</div>
);
}
⚠️ เจอ error composite index ไม่พอ?
เมื่อคุณใช้ .where() และ .orderBy() พร้อมกัน → อาจเกิด error เช่น:
FirebaseError: The query requires an index.
You can create it here: https://console.firebase.google.com/.../indexes?create_composite=...
🛠 วิธีสร้าง Composite Index
- อ่านลิงก์ใน error แล้วคลิก → จะพาไปยังหน้า “สร้าง Index” ใน Firebase Console
- คลิก "Create Index" → รอประมาณ 1–2 นาที
- ลองโหลดข้อมูลใหม่อีกครั้ง
🔧 หรือไปที่ Firestore → Indexes → Composite → กด “Add Index” ด้วยตนเอง
📊 กรณีศึกษาการค้นหาด้วยหลายเงื่อนไข (status + createdAt)
สมมุติ: ต้องการแสดงเฉพาะโพสต์ที่ถูก “อนุมัติ” และเรียงตามวันที่โพสต์
where('status', '==', 'approved')orderBy('createdAt', 'desc')
🧠 ต้องสร้าง Composite Index ด้วย field ทั้งสอง:
status (asc)+createdAt (desc)
🧩 UI ตัวอย่าง (Next.js)
<ul>
{items.map(post => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.status} • {new Date(post.createdAt.seconds * 1000).toLocaleString()}</p>
</li>
))}
</ul>
การใช้ startAfter, limit, orderBy และ where อย่างเหมาะสมทำให้คุณสามารถสร้างระบบ pagination และ filtering ที่เสถียรและปลอดภัยบน Firestore ได้ดีขึ้น พร้อมควบคุม performance และ UX ได้ในระดับ production