在 React Native 中使用 Firebase Firestore 建構動態產品篩選器元件


摘要

在這篇文章中,我們將探討如何在 React Native 中利用 Firebase Firestore 建構一個動態的產品篩選器元件,這對於提升用戶體驗至關重要。 歸納要點:

  • 利用 Firebase Firestore 的即時更新機制,搭配 `onSnapshot` 方法,讓產品篩選結果能隨著使用者的調整即時反應,提高使用者體驗
  • 透過 Firestore 的 `where` 查詢條件及 `orderBy` 和 `limit` 功能,將篩選邏輯轉移到資料庫端,有效減少前端運算與資料傳輸,提升效能。
  • 結合 GraphQL 提供靈活的查詢接口,使複雜篩選條件更易管理,同時探索第三方套件如 `react-native-elements` 和 `react-native-firestore` 簡化開發流程。
透過即時資料同步、效能優化以及靈活的查詢解決方案,我們可以打造出流暢且高效的產品篩選器。

npm install @react-native-firebase/app @react-native-firebase/firestore

接下來,在您的應用程式中配置 Firebase,方法是將 Firebase 憑證新增至 config/config.js(請用您的配置取代此部分):

import { initializeApp } from 'firebase/app'; import { getFirestore } from 'firebase/firestore';  const firebaseConfig = {   apiKey: "YOUR_API_KEY",   authDomain: "YOUR_PROJECT_ID.firebaseapp.com",   projectId: "YOUR_PROJECT_ID",   storageBucket: "YOUR_PROJECT_ID.appspot.com",   messagingSenderId: "YOUR_MESSAGING_SENDER_ID",   appId: "YOUR_APP_ID", };  const app = initializeApp(firebaseConfig); const db = getFirestore(app);  export { db };

接下來,我們將建立一個動態的復選框元件,從 Firestore 獲取產品品牌並將其顯示為復選框。以下是我們的分解步驟:獲取品牌:我們將從 Firestore 拉取產品名稱,並提取每個名稱的第一個單詞作為品牌。動態復選框:我們將為每個唯一品牌動態建立復選框,並包含一個「其他」選項以便於非標準品牌的選擇。實時過濾:當某個復選框被選中時,產品列表將根據所選品牌進行過濾。

import React, { useState, useEffect } from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import { collection, query, getDocs, where } from 'firebase/firestore'; import { db } from '../config/config';  const CheckBox = ({ products, updateProducts }) => {   const [brandCheckboxes, setBrandCheckboxes] = useState({});   const [isLoading, setIsLoading] = useState(true);    // Fetch brands from Firestore   useEffect(() => {     const fetchBrands = async () => {       const querySnapshot = await getDocs(collection(db, 'Product_details'));       const brandsSet = new Set();        querySnapshot.forEach((doc) => {         const productName = doc.data().Product_Name;         if (productName) {           const firstWord = productName.split(' ')[0];           brandsSet.add(firstWord);         }       });        const dynamicCheckboxes = {};       brandsSet.forEach((brand) => {         dynamicCheckboxes[brand] = false; // Initialize each brand with unchecked state       });       dynamicCheckboxes['Others'] = false; // Add "Others" option        setBrandCheckboxes(dynamicCheckboxes);       setIsLoading(false);     };      fetchBrands();   }, []);    // Handle filtering based on selected checkboxes   const handleSearch = async (selectedBrands) => {     const productRef = collection(db, 'Product_details');     const brandQueries = Object.keys(selectedBrands).map((brandName) => {       if (selectedBrands[brandName]) {         return query(productRef, where('Product_Name', '>=', brandName), where('Product_Name', '<', brandName + '\uf8ff'));       }       return null;     });      const queryPromises = brandQueries.filter((query) => query !== null).map((q) => getDocs(q));     const querySnapshots = await Promise.all(queryPromises);     const results = [];      querySnapshots.forEach((snapshot) => {       snapshot.forEach((doc) => {         results.push(doc.data());       });     });      updateProducts(results); // Update the products based on filtered results   };    // Handle checkbox state change   const handleCheckboxChange = (brandName) => {     setBrandCheckboxes((prevCheckboxes) => ({       ...prevCheckboxes,       [brandName]: !prevCheckboxes[brandName],     }));      const selectedBrands = { ...brandCheckboxes };     selectedBrands[brandName] = !selectedBrands[brandName];     handleSearch(selectedBrands); // Trigger search on checkbox toggle   };    if (isLoading) {     return (                Loading brands...            );   }    return (            Filters       {Object.keys(brandCheckboxes).map((brandName) => (          handleCheckboxChange(brandName)}           style={styles.checkbox}         >                                   {brandName}                           ))}        ); };  const styles = StyleSheet.create({   loadingContainer: {     flex: 1,     justifyContent: 'center',     alignItems: 'center',   },   checkBoxContainer: {     marginTop: 10,   },   filterHeading: {     fontSize: 10,     fontWeight: 'bold',     marginBottom: 5,   },   checkbox: {     flexDirection: 'row',     alignItems: 'center',     marginBottom: 10,   },   checkboxBox: {     width: 10,     height: 10,     borderWidth: 1,     borderColor: 'black',     marginRight: 5,   },   checkedBox: {     backgroundColor: 'black',   },   uncheckedLabel: {     fontSize: 8,   },   checkedLabel: {     fontSize: 8,     fontWeight: 'bold',   }, });  export default CheckBox;

使用 React Native 核取方塊篩選元件,結合 Firebase Firestore 進行動態產品篩選

從 Firebase 擷取資料:我們使用 `getDocs` 方法來檢索 `Product_details` 集合中的所有檔案。接著,我們提取每個產品名稱的第一個單詞,以此代表品牌。

動態核取方塊建立:根據從 Firestore 獲取的品牌資訊,我們為每一個獨特的品牌動態建立核取方塊,並將它們繫結到元件狀態。

即時篩選:當任何一個核取方塊被切換時,狀態會隨之更新,並觸發 Firestore 查詢來篩選符合所選品牌的產品。我們利用 Firestore 的 `where` 子句進行基於品牌的篩選。

UI 載入狀態:在從 Firebase 獲取品牌資料期間,會顯示一條簡單的載入訊息,以表明資料仍在檢索中。

這裡是一篇以您的 React Native 核取方塊篩選元件及其使用 Firebase Firestore 為主題的精心記錄文章草稿。

使用 Firebase Firestore 和 GraphQL 建立動態產品過濾系統

在本文中,我們將探討如何在 React Native 中使用 Firebase Firestore 建立一個動態產品過濾系統。我們將建立一個勾選框過濾器,讓使用者可以依品牌篩選產品,並從 Firestore 動態提取資料。在開始之前,請確保您已經設定以下環境:對 React Native 和 Firebase 的基本了解;啟用了 Firestore 的 Firebase 專案;名為 Product_details 的 Firestore 集合,其中包含具有 Product_Name 欄位的文件。

如果您尚未將 Firebase 整合到您的 React Native 專案中,需要進行這項操作。您可以按照 Firebase 的 React Native 設定指南進行配置。對於本專案,我們將使用 Firestore 資料庫,因此請務必安裝必要的 Firebase 依賴項。

傳統上,React Native 與 Firebase 的資料存取主要依賴 Firestore SDK。隨著 GraphQL 的普及,許多開發者開始探索將 GraphQL 整合到 Firebase 的可能性。近期,Firebase 推出了 `Firestore for GraphQL` 的預覽版,此技術使開發者能夠透過 GraphQL 語法輕鬆地存取 Firestore 資料,同時利用 GraphQL 強大的功能,例如資料關聯、巢狀查詢以及型別系統,以進一步最佳化應用程式架構

具體而言,在產品過濾系統中,你可以利用 GraphQL 的資料關聯功能,將品牌資料與產品資料建立關聯,並透過單一的 GraphQL 查詢,同時獲得產品資訊和品牌資訊,簡化資料取得流程,提高應用程式效能。因此,在設計此類系統時,不妨考慮運用最新技術來提升效能及使用者體驗。

npm install @react-native-firebase/app @react-native-firebase/firestore

接下來,在您的應用程式中配置 Firebase,方法是將 Firebase 憑證新增到 config/config.js 中(請將此替換為您的配置):

import { initializeApp } from 'firebase/app'; import { getFirestore } from 'firebase/firestore';

接下來,我們將建立一個動態的核取方塊元件,從 Firestore 獲取產品品牌並將其顯示為核取方塊。以下是我們的分解步驟:抓取品牌:我們將從 Firestore 提取產品名稱,並提取每個名稱的第一個單詞作為品牌。動態核取方塊:我們將為每個獨特品牌動態建立核取方塊,並包括一個「其他」選項以供非標準品牌使用。即時過濾:當選擇某個核取方塊時,產品列表將根據所選品牌進行過濾。讓我們深入程式碼吧!

javascript

Copy code

import React, { useState, useEffect } from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import { collection, query, getDocs, where } from 'firebase/firestore'; import { db } from '../config/config';

載入品牌... 過濾器 {Object.keys(brandCheckboxes).map((brandName) => ( handleCheckboxChange(brandName)} style={styles.checkbox} > {brandName} ))}


動態過濾產品:利用 Firebase Firestore 和 React Native 建立即時品牌篩選

從 Firebase 獲取資料:我們使用 getDocs 方法來檢索 Product_details 集合中的所有文件。接著,我們提取每個產品名稱的第一個字,以表示品牌。動態建立勾選框:根據從 Firestore 獲取的品牌,我們動態地為每個獨特的品牌建立勾選框,每個勾選框都與元件狀態相關聯。即時過濾:每當切換一個勾選框時,狀態會更新,並觸發 Firestore 查詢以過濾符合所選品牌的產品。我們利用 Firestore 的 where 子句進行基於品牌的過濾。使用者介面載入狀態:在從 Firebase 獲取品牌期間,顯示一條簡單的載入訊息,以指示資料仍在檢索中。

透過實施這種動態過濾系統,你可以為任何需要基於資料的過濾應用程式建立一個高度可定製化的產品篩選器。本範例展示瞭如何利用 Firebase Firestore 的查詢能力和 React Native 的狀態管理來建立一個能夠根據使用者輸入即時調整互動式使用者介面。在此基礎上,可以進一步最佳化查詢效能,例如採用分頁載入(Pagination),或結合 Firebase Cloud Functions 實現更複雜的篩選邏輯,使得整體系統更加高效且靈活。

您可以自由擴充套件這個範例,加入更高階的篩選條件,例如價格範圍、類別或評分。Firebase 和 React Native 的靈活性將使您能夠根據需求擴充套件解決方案。


MD

專家

相關討論

❖ 相關專欄