将存储在Firebase中的值相加并在FutureBuilder中显示总计

时间:2020-09-14 19:07:02

标签: firebase flutter google-cloud-firestore

我正在尝试从Firebase检索每月费用列表,将每个每月费用的金额相加并显示在FutureBuilder中。 在“文本”小部件中,我只是得到了null。在过去的半个小时里一直在尝试用Google搜索答案,但是我什至不知道从哪里开始搜索。

试图抛出一些打印语句以查看发生了什么,但是我在提供者调用之后输入的任何打印语句都没有显示。

编辑:在注释行中添加了Future强制转换。仍然没有运气。但忽略了该变量,而是直接从FutureBuilder中调用了future函数。现在所有的打印语句都在工作,并且正在返回“ MonthlyExpense”的实例。仍然为空。

class SummaryView extends StatefulWidget {
  @override
  _SummaryViewState createState() => _SummaryViewState();
}

class _SummaryViewState extends State<SummaryView> {
  

  /*  Removed future variable and initState()
  Future<double> _totalExpensesAmount; //Future<double> added

  @override
  void initState() {
    super.initState();
    print("init");
    _totalExpensesAmount = _getTotalExpensesAmount();
  }
  */

  Future<double> _getTotalExpensesAmount() async { //Future<double> added
    print("started");
    final user = Provider.of<BPUser>(context);
    print("user: $user");
    double expensesTotal = 0.0;

    var snapshot = await FirebaseFirestore.instance
        .collection("BPUsers/${user.uid}/monthlyexpenses")
        .get();
    print(snapshot);
    List<MonthlyExpense> searchedProducts =
        DatabaseService().monthlyExpenseListFromSnapshot(snapshot);
    print(searchedProducts);
    for (var i = searchedProducts.length; i >= 1; i--) {
      expensesTotal += double.parse(searchedProducts[i].amount);
    }
    return Future<double>expensesTotal; //Future<double> added
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: mainBackgroundColor,
      body: Column(
        children: [
          Container(
            child: FutureBuilder(
                future: _getTotalExpensesAmount(), // called the function directly
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    return Text(
                      "${snapshot.data}",
                      style: nameStyle,
                    );
                  } else {
                    return Text("Loading...");
                  }
                }),
          )
        ],
      ),
    );
  }
}

monthlyExpenseListFromSnapshot函数(在我使用它的另一个小部件中完美运行):

List<MonthlyExpense> monthlyExpenseListFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.docs.map((doc) {
      return MonthlyExpense(
          name: doc.data()['name'] ?? '',
          amount: doc.data()['amount'] ?? '',
          isActive: doc.data()['isActive']);
    }).toList();
  }

firebase数据库: enter image description here

3 个答案:

答案 0 :(得分:1)

您的getExpensesTotal不会返回未来。因此,widgetv将永远不会重建,因为已经计算了数据。 FutureBuilder和StreamBuilder仅在初始构建后加载数据后才导致重建。尝试用Future.value来解决费用总计。

答案 1 :(得分:1)

您需要定义函数的签名以表示期望的功能,在这种情况下为Future <double>

// ....
Future<double> _getTotalExpensesAmount() async {

答案 2 :(得分:1)

第一个问题是跳过变量和init调用,并调用_getTotalExpensesAmount()future函数(向其中添加Future签名)。

第二,我的for循环是错误的。需要将条件更改为:

for (var i = searchedProducts.length - 1; i >= 0; i--) {

现在一切正常!