Flutter 如何在 Firestore 中组合多个文档中的值以与列表中的相应卖家一起显示

Posted

技术标签:

【中文标题】Flutter 如何在 Firestore 中组合多个文档中的值以与列表中的相应卖家一起显示【英文标题】:Flutter How to combine values from multiple documents in Firestore to display alongside corresponding sellers in list 【发布时间】:2022-01-17 16:41:08 【问题描述】:

我有许多销售发票的 Firestore 集合。每张发票包含:

买家(姓名) 卖家(姓名) 价值 ($)

在我的 Flutter 应用中,我想创建一个所有卖家的列表以及他们的每个总收入(他们所有发票的总价值。)

最好的方法是什么?我很迷茫,需要帮助。

【问题讨论】:

【参考方案1】:

我想出了一种方法来实现我想要的,但肯定还有改进的余地:

Future<List<DataTableRow>> getDataTableRows() async 

  FirebaseFirestore _firestoreInstance = FirebaseFirestore.instance;

  // /// /// /// Get a List of Sellers /// /// /// //

  List<Seller> listOfSellers = [];
  var snapshotOfSellers =
      await _firestoreInstance.collection('sellers').get();
  listOfSellers = snapshotOfSellers.docs.map(
    (DocumentSnapshot<Map<String, dynamic>> doc) 
      return Seller(
        sellerID: doc.data()!['sellerID'],
      );
    ,
  ).toList();

  // /// /// /// Get a List of Invoices /// /// /// //

  List<Invoice> listOfInvoices = [];
  var snapshotOfInvoices = await _firestoreInstance
      .collection('invoices')
      .get();
  listOfInvoices = snapshotOfInvoices.docs.map(
    (DocumentSnapshot<Map<String, dynamic>> doc) 
      return Invoice(
        buyerID: doc.data()!['buyerID'],
        sellerID: doc.data()!['sellerID'],
        value: doc.data()!['value'],
      );
    ,
  ).toList();

  // /// /// /// Create a List of Lists of Invoices /// /// /// //

  List<List<Invoice>> listOfLists = [];
  listOfLists = listOfSellers
      .map((seller) => listOfInvoices
          .where((invoice) => invoice.sellerID == seller.sellerID)
          .toList())
      .toList();

  // /// /// /// Get a Sum of all Invoices Combined /// /// /// //

  final salesValues =
      listOfInvoices.map((invoice) => invoice.value.toDouble() ?? 0.0);
  final totalSum = await salesValues.reduce((a, b) => a + b);

  // /// /// /// Create a List of DataTableRows /// /// /// //

  List<DataTableRow> listOfDataTableRows = [];
  listOfDataTableRows = listOfLists.map((invoicesLists) 
    var salesSum = invoicesLists
        .fold<num>(0, (previous, value) =>
        previous + value.value).toInt();

    return DataTableRow(
      sellerID: invoicesLists.first.sellerID,
      sales: salesSum,
      shareOfTotalSales: salesSum / totalSum * 100,
    );
  ).toList();

  listOfDataTableRows.sort((a, b) => b.salesSum.compareTo(a.salesSum));

  return listOfDataTableRows;








// /// /// /// Build Data Table /// /// /// //


class MyDataTable extends StatefulWidget 
  @override
  _MyDataTableState createState() => _DataTableState();


class _MyDataTableState extends State<MyDataTable> 
  Future<List<Row>> listOfRowsFuture = getDataTableRows();

  @override
  Widget build(BuildContext context) 
    return FutureBuilder(
      future: listOfRowsFuture,
      builder: (context, AsyncSnapshot<List<Row>> snapshot) 
        if (snapshot.hasError) 
          return Container(
            padding: EdgeInsets.all(50),
            child: Center(
              child: Text(
                'Something went wrong',
                style: Theme.of(context).textTheme.headline4!,
              ),
            ),
          );
        

        if (snapshot.connectionState == ConnectionState.waiting) 
          return Container(
            padding: EdgeInsets.all(50),
            child: Center(
              child: CircularProgressIndicator(),
            ),
          );
        

        List<Row>? listOfRows = snapshot.data ?? [];

        final columnHeaders = [
          'Seller ID',
          'Sales £',
          'Share of Total Sales %',
        ];

        // // Get Columns // //
        List<DataColumn> getColumns(List<String> columnHeaders) =>
            columnHeaders.map((String column) 
                return DataColumn(
                  label: Text('$column'),
                );
            ).toList();

        // // Get Cells // //
        List<DataCell> getCells(List<dynamic> cells) => cells.map((data) 
                return DataCell(
                    child: SelectableText('$data'),
                );
            ).toList();

        // // Get Rows // //
        List<DataRow> getRows(List<Row> rows) =>
            rows.map((row) 
              final cells = [
                row.sellerID,
                row.sales,
                row.shareOfTotalSales,
              ];

              return DataRow(cells: getCells(cells));
            ).toList();

        // // Return Table // //
        return DataTable(
          columns: getColumns(columnHeaders),
          rows: getRows(listOfRows),
        );
      ,
    );
  

【讨论】:

以上是关于Flutter 如何在 Firestore 中组合多个文档中的值以与列表中的相应卖家一起显示的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter中从云Firestore中获取数据?

如何在flutter中获取firestore文档的documentid?

如何在 Flutter 中读取 Firestore 时间戳

如何从flutter中的firestore文档字段中获取数据?

如何在 Flutter Firestore 提供程序中显示数据

如何使用 Firestore 在 Flutter 中搜索文本