Firebase এর হাতেখড়ি (পর্ব ৭) – Read, Query ও Pagination

Firebase Realtime Database Read ও Query

আগের পর্বে set(), push(), update() দিয়ে ডেটা লিখতে শিখেছিলাম। এবার সময় সেই ডেটা ফিরে পড়ার — এই পর্বে শিখব get() আর onValue() দিয়ে ডেটা পড়া, orderByChild, equalTo দিয়ে ফিল্টার করা, আর limitToFirst/limitToLast দিয়ে Pagination।

get() — একবার ডেটা আনা

get() একবার ডেটা fetch করে, ঠিক সাধারণ API কলের মতো — ডেটা পরে পাল্টালেও আবার fetch না করলে জানা যাবে না।

import { getDatabase, ref, get } from "firebase/database";
import { app } from "./firebase";

const db = getDatabase(app);

async function fetchBooks() {
  const snapshot = await get(ref(db, "books"));
  if (snapshot.exists()) {
    console.log(snapshot.val()); // পুরো অবজেক্ট
  } else {
    console.log("কোনো বই নেই");
  }
}

লক্ষ্য করুন — get() সরাসরি ডেটা রিটার্ন করে না, একটা snapshot রিটার্ন করে। snapshot.exists() দিয়ে চেক করা আর snapshot.val() দিয়ে আসল ডেটা বের করা — এই প্যাটার্নটা RTDB-এর প্রায় সব read অপারেশনে থাকবে।

onValue() — লাইভ, রিয়েল-টাইম আপডেট

RTDB-এর আসল শক্তি এখানে — onValue() একটা লিসেনার বসায়, ডেটা যতবারই পাল্টাক না কেন (নিজের দিক থেকে, বা অন্য কোনো ইউজারের দিক থেকে), সাথে সাথে callback চলে।

import { getDatabase, ref, onValue } from "firebase/database";
import { app } from "./firebase";

const db = getDatabase(app);

const booksRef = ref(db, "books");
const unsubscribe = onValue(booksRef, (snapshot) => {
  const data = snapshot.val();
  console.log("লাইভ আপডেট পেলাম:", data);
});

// পরে যখন আর শোনার দরকার নেই
// unsubscribe();

React-এ এটা React এর হাতেখড়ি পর্ব ১৭-এর মতো useEffect-এর ভেতর বসিয়ে cleanup-এ unsubscribe() কল করা হয় — Firebase এর হাতেখড়ি পর্ব ৩-এর onAuthStateChanged-এর মতোই একটা প্যাটার্ন।

function useBooks() {
  const [books, setBooks] = React.useState({});

  React.useEffect(() => {
    const booksRef = ref(db, "books");
    const unsubscribe = onValue(booksRef, (snapshot) => {
      setBooks(snapshot.val() || {});
    });
    return () => unsubscribe();
  }, []);

  return books;
}

get() vs onValue() — কখন কোনটা

  • get() — একবার ডেটা লাগলেই যথেষ্ট (যেমন কোনো ফর্ম সাবমিট করার আগে চেক করা)
  • onValue() — ডেটা লাইভ দেখাতে হবে (যেমন চ্যাট, ড্যাশবোর্ড, লাইভ স্কোর)

onValue() বেশি সুবিধাজনক মনে হলেও, প্রতিটা কম্পোনেন্টে লিসেনার বসিয়ে রাখলে অপ্রয়োজনীয় ডেটা ট্রান্সফার বাড়ে — তাই যেখানে সত্যিই লাইভ আপডেট দরকার নেই, সেখানে get()-ই যথেষ্ট।

Query — orderByChild ও equalTo দিয়ে ফিল্টার

শুধু path দিয়ে ডেটা আনলে সব ডেটা চলে আসে। নির্দিষ্ট শর্তে ফিল্টার করতে query(), orderByChild(), আর equalTo() একসাথে ব্যবহার করতে হয়।

import { getDatabase, ref, query, orderByChild, equalTo, get } from "firebase/database";
import { app } from "./firebase";

const db = getDatabase(app);

async function getBooksByAuthor(authorName) {
  const booksQuery = query(
    ref(db, "books"),
    orderByChild("author"),
    equalTo(authorName)
  );
  const snapshot = await get(booksQuery);
  return snapshot.val();
}

// ব্যবহার
getBooksByAuthor("বিভূতিভূষণ").then((books) => console.log(books));

গুরুত্বপূর্ণ: orderByChild দিয়ে যে ফিল্ডে query করছেন (এখানে author), সেটা Console-এর Rules-এ একটা .indexOn হিসেবে যোগ করতে হয়, নাহলে বড় ডেটাসেটে Firebase warning দেবে ও ধীরগতি হবে — এটা পরের সিকিউরিটি পর্বে বিস্তারিত দেখব।

Pagination — limitToFirst ও limitToLast

বড় লিস্ট একসাথে না এনে ধাপে ধাপে আনতে limitToFirst() বা limitToLast() ব্যবহার হয়।

import { query, orderByChild, limitToFirst, limitToLast } from "firebase/database";

// সবচেয়ে পুরনো ৫টা বই
const oldestFive = query(ref(db, "books"), orderByChild("year"), limitToFirst(5));

// সবচেয়ে নতুন ৫টা বই
const newestFive = query(ref(db, "books"), orderByChild("year"), limitToLast(5));

এভাবে "Load More" বাটন বানাতে সাধারণত শেষ আইটেমের key মনে রেখে পরের ব্যাচে startAfter() ব্যবহার করা হয় — এটা RTDB-তে একটু ম্যানুয়াল কাজ, Firestore-এর মতো বিল্ট-ইন cursor নেই (পর্ব ৪-এর তুলনা মনে আছে?)।

লাইভ ডেমো — Query ও Pagination (সিমুলেটেড)

নিচে একটা বইয়ের লিস্ট আছে — লেখক দিয়ে ফিল্টার করো, বা "আরও দেখাও" চেপে limitToFirst-এর মতো ধাপে ধাপে ডেটা লোড হতে দেখো।

নিজে চেষ্টা করো

Exercise:

  1. get() দিয়ে নিজের books নোড থেকে একবার সব ডেটা fetch করো।
  2. onValue() বসাও, তারপর Console থেকে ম্যানুয়ালি একটা বই যোগ করে দেখো লিসেনার সাথে সাথে নতুন ডেটা দেখাচ্ছে কিনা।
  3. orderByChild("author") আর equalTo() দিয়ে একটা নির্দিষ্ট লেখকের সব বই খুঁজে বের করো।
  4. limitToFirst(3) দিয়ে প্রথম ৩টা বই আনো, তারপর limitToLast(3) দিয়ে শেষ ৩টা এনে পার্থক্য বোঝার চেষ্টা করো।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব Security Rules গভীরভাবে — Read/Write rules কীভাবে লিখতে হয়, auth-based access control, আর কেন Test mode-এর খোলা Rules প্রোডাকশনে ব্যবহার করা বিপজ্জনক।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম