N

Nokfa Docs

Current: framework-next.js

ไม่มีชื่อบทความ

🔍 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

  1. อ่านลิงก์ใน error แล้วคลิก → จะพาไปยังหน้า “สร้าง Index” ใน Firebase Console
  2. คลิก "Create Index" → รอประมาณ 1–2 นาที
  3. ลองโหลดข้อมูลใหม่อีกครั้ง

🔧 หรือไปที่ 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