You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中按类别名称从Firebase Firestore筛选产品数据

Flutter从Firebase Firestore按类别获取产品数据

1. 前置准备

  • 确认Flutter项目已完成Firebase集成,在pubspec.yaml中添加cloud_firestore依赖:
dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^4.15.0 # 替换为最新版本

执行flutter pub get安装依赖。

2. 核心实现代码

从你的数据结构来看,products集合下的每个文档都包含category字段,直接用where条件就能按类别过滤数据,下面提供两种常用实现方式:

方式一:一次性获取数据(适合非实时场景)

用FutureBuilder一次性拉取对应类别的产品数据:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class CategoryProductsPage extends StatelessWidget {
  final String targetCategory; // 传入要查询的类别名称,比如"Electronics"

  const CategoryProductsPage({super.key, required this.targetCategory});

  // 封装查询方法
  Future<List<Map<String, dynamic>>> _fetchProducts() async {
    final querySnapshot = await FirebaseFirestore.instance
        .collection('products')
        .where('category', isEqualTo: targetCategory)
        .get();
    
    return querySnapshot.docs
        .map((doc) => doc.data() as Map<String, dynamic>)
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('${targetCategory}类产品')),
      body: FutureBuilder<List<Map<String, dynamic>>>(
        future: _fetchProducts(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return Center(child: Text('加载失败:${snapshot.error}'));
          }
          if (snapshot.data?.isEmpty ?? true) {
            return const Center(child: Text('该类别暂无产品'));
          }

          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              final product = snapshot.data![index];
              return ListTile(
                title: Text(product['name'] ?? '未命名'),
                subtitle: Text('价格:\$${product['price']}'),
                leading: product['imageUrl'] != null
                    ? Image.network(product['imageUrl'], width: 50)
                    : const Icon(Icons.image_not_supported),
              );
            },
          );
        },
      ),
    );
  }
}

方式二:实时监听数据(适合需要同步更新的场景)

用StreamBuilder实时监听Firestore中对应类别的数据变化:

// 替换上述代码中的_fetchProducts方法,改为返回Stream
Stream<QuerySnapshot> _listenProducts() {
  return FirebaseFirestore.instance
      .collection('products')
      .where('category', isEqualTo: targetCategory)
      .snapshots();
}

// 替换build中的FutureBuilder为StreamBuilder
body: StreamBuilder<QuerySnapshot>(
  stream: _listenProducts(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(child: CircularProgressIndicator());
    }
    if (snapshot.hasError) {
      return Center(child: Text('加载失败:${snapshot.error}'));
    }
    final docs = snapshot.data?.docs ?? [];
    if (docs.isEmpty) {
      return const Center(child: Text('该类别暂无产品'));
    }

    return ListView.builder(
      itemCount: docs.length,
      itemBuilder: (context, index) {
        final product = docs[index].data() as Map<String, dynamic>;
        return ListTile(
          title: Text(product['name'] ?? '未命名'),
          subtitle: Text('价格:\$${product['price']}'),
          leading: product['imageUrl'] != null
              ? Image.network(product['imageUrl'], width: 50)
              : const Icon(Icons.image_not_supported),
        );
      },
    );
  },
),

3. 注意事项

  • 检查Firestore安全规则,确保允许读取products集合,开发阶段可临时设置宽松规则(上线后需收紧):
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /products/{product} {
      allow read: if true; // 开发用,上线替换为身份验证逻辑
      allow write: if request.auth != null;
    }
  }
}
  • 处理字段空值:比如imageUrl为空时,用占位图标替代,避免图片加载报错。
  • 类别名称需严格匹配Firestore中的字段值,大小写、拼写错误会导致查询不到数据。

内容的提问来源于stack exchange,提问作者Ahmed Dulap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:36:18