首页 > 解决方案 > Flutter Firebase 实时数据库问题

问题描述

这是我的问题:

我想要的是从数据库中提取信息,每个类别有多少案例,并在列表中显示此信息。这意味着 - 显示类别的名称以及每个类别有多少孩子(案例)(totalCases)......

我使用功能 getNumberOfNodes 从数据库中读取数据,因此我可以通过使用未来的构建器获取一个类别的子项(案例)的数量。

但:

如果我执行代码,我现在会得到所有类别的名称以及 FIRST 类别拥有的子项(案例)的数量。

我做错了什么?

这是我的代码,我正在努力:

import '../components/category_list_tile.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import '../constants.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'dart:async';

class ScreenCategoryList extends StatefulWidget {
  static String id = 'screen_category_list';
  final FirebaseApp app;

  ScreenCategoryList({this.app});
  @override
  _ScreenCategoryListState createState() => _ScreenCategoryListState();
}

class _ScreenCategoryListState extends State<ScreenCategoryList> {
  final referenceDatabase = FirebaseDatabase.instance;
  //final _dbRef = FirebaseDatabase.instance.reference().child("de");
  int counter = 0;
  bool showSpinner = false;
  DatabaseReference _databaseReference;

  @override
  void initState() {
    final FirebaseDatabase database = FirebaseDatabase(app: widget.app);
    _databaseReference = database.reference().child("de");
    super.initState();
  }

  Future<int> getNumberOfNodes(int counter) async {
    final response = await FirebaseDatabase.instance
        .reference()
        .child('de')
        .child('category')
        .child('$counter')
        .child('cases')
        .once();
    var nodes = [];
    response.value.forEach((v) => nodes.add(v));
    print(nodes.length);
    counter++;
    return nodes.length;
  }

  @override
  Widget build(BuildContext context) {
    int counter = 0;
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [Colors.white, Colors.white],
        ),
        image: const DecorationImage(
            image: AssetImage("images/background.png"), fit: BoxFit.cover),
      ),
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar: AppBar(
          toolbarHeight: 60.0,
          elevation: 0.0,
          backgroundColor: Colors.black12,
          leading: Padding(
              padding: EdgeInsets.only(left: 12.0, top: 12.0, bottom: 12.0),
              child: Image(image: AssetImage('images/lexlogo_black.png'))),
          title: Center(
            child: Column(
              children: [
                Text(
                  'Kategorien',
                  style: TextStyle(
                      color: kMainDarkColor,
                      fontFamily: 'Roboto',
                      fontSize: 21.0,
                      fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ),
          actions: [
            Padding(
              padding: EdgeInsets.only(right: 8.0),
              child: IconButton(
                icon: Icon(Icons.more_vert_rounded),
                iconSize: 30.0,
                color: kMainDarkColor,
                onPressed: () {},
                //onPressed: onPressMenuButton,
              ),
            ),
          ],
        ),
        body: FutureBuilder<int>(
          future: getNumberOfNodes(counter),
          builder: (BuildContext context, AsyncSnapshot<int> casesSnapshot) {
            if (casesSnapshot.hasData) {
              return FirebaseAnimatedList(
                reverse: false,
                padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
                query: _databaseReference.child('category'),
                itemBuilder: (
                  BuildContext context,
                  DataSnapshot categorySnapshot,
                  Animation<double> animation,
                  int index,
                ) {
                  int numberOfCases = casesSnapshot.data;
                  print('$counter, $numberOfCases');
                  return CategoryListTile(
                    title: categorySnapshot.value['name'].toString(),
                    successfulCases: 10,
                    totalCases: casesSnapshot.data,
                    onTitleClick: () {},
                    onInfoButtonClick: () {},
                  );
                },
              );
            } else if (casesSnapshot.hasError) {
              return Center(
                child: Column(
                  children: [
                    Icon(
                      Icons.error_outline,
                      color: Colors.red,
                      size: 60,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 16),
                      child: Text('Error: ${casesSnapshot.error}'),
                    )
                  ],
                ),
              );
            } else {
              return Center(
                child: Column(
                  children: [
                    SizedBox(
                      child: CircularProgressIndicator(),
                      width: 60,
                      height: 60,
                    ),
                    Padding(
                      padding: EdgeInsets.only(top: 16),
                      child: Text('Awaiting result...'),
                    )
                  ],
                ),
              );
            }
          },
        ),
      ),
    );
  }
}

标签: flutterfirebase-realtime-database

解决方案


知道了...

这是对我有用的代码:

class _ScreenCategoryListState extends State<ScreenCategoryList> {
  final referenceDatabase = FirebaseDatabase.instance;

  bool showSpinner = false;
  DatabaseReference _databaseReference;

  @override
  void initState() {
    final FirebaseDatabase database = FirebaseDatabase(app: widget.app);
    _databaseReference = database.reference().child("de");
    super.initState();
  }

  Future<Map<int, int>> getNumberOfNodes() async {
    Map<int, int> caseNumbers = new Map<int, int>();
    // read number of category nodes
    final categoriesNumbersResponse = await FirebaseDatabase.instance
        .reference()
        .child('de')
        .child('category')
        // .child('0')
        // .child('cases')
        .once();
    var categoryNodes = [];
    categoriesNumbersResponse.value.forEach((v) => categoryNodes.add(v));
    int numberOfCategories = categoryNodes.length;

    //read number of cases in category
    for (int i = 0; i < numberOfCategories; i++) {
      final caseResponse = await FirebaseDatabase.instance
          .reference()
          .child('de')
          .child('category')
          .child('$i')
          .child('cases')
          .once();
      var caseNodes = [];
      caseResponse.value.forEach((v) => caseNodes.add(v));
      int numberOfCases = caseNodes.length;
      caseNumbers[i] = numberOfCases;
    }
    return caseNumbers;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [Colors.white, Colors.white],
        ),
        image: const DecorationImage(
            image: AssetImage("images/background.png"), fit: BoxFit.cover),
      ),
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar: AppBar(
          toolbarHeight: 60.0,
          elevation: 0.0,
          backgroundColor: Colors.black12,
          leading: Padding(
              padding: EdgeInsets.only(left: 12.0, top: 12.0, bottom: 12.0),
              child: Image(image: AssetImage('images/lexlogo_black.png'))),
          title: Center(
            child: Column(
              children: [
                Text(
                  'Kategorien',
                  style: TextStyle(
                      color: kMainDarkColor,
                      fontFamily: 'Roboto',
                      fontSize: 21.0,
                      fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ),
          actions: [
            Padding(
              padding: EdgeInsets.only(right: 8.0),
              child: IconButton(
                icon: Icon(Icons.more_vert_rounded),
                iconSize: 30.0,
                color: kMainDarkColor,
                onPressed: () {},
                //onPressed: onPressMenuButton,
              ),
            ),
          ],
        ),
        body: FutureBuilder<Map<int, int>>(
          future: getNumberOfNodes(),
          builder: (BuildContext context,
              AsyncSnapshot<Map<int, int>> casesSnapshot) {
            if (casesSnapshot.hasData) {
              return FirebaseAnimatedList(
                reverse: false,
                padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
                query: _databaseReference.child('category'),
                itemBuilder: (
                  BuildContext context,
                  DataSnapshot categorySnapshot,
                  Animation<double> animation,
                  int index,
                ) {
                  int numberOfCases = casesSnapshot.data[index];
                  //print('number  of cases  $_counter, $numberOfCases');
                  return CategoryListTile(
                    title: categorySnapshot.value['name'].toString(),
                    successfulCases: 10,
                    totalCases: numberOfCases,
                    onTitleClick: () {},
                    onInfoButtonClick: () {},
                  );
                },
              );
            } else if (casesSnapshot.hasError) {
              return Center(
                child: Column(
                  children: <Widget>[
                    Icon(
                      Icons.error_outline,
                      color: Colors.red,
                      size: 60,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 16),
                      child: Text('Error: ${casesSnapshot.error}'),
                    )
                  ],
                ),
              );
            } else {
              return Center(
                child: Column(
                  children: <Widget>[
                    SizedBox(
                      child: CircularProgressIndicator(),
                      width: 60,
                      height: 60,
                    ),
                    Padding(
                      padding: EdgeInsets.only(top: 16),
                      child: Text('Awaiting result...'),
                    )
                  ],
                ),
              );
            }
          },
        ),
      ),
    );
  }
}

推荐阅读