flutterfirebasefilterdisplay

Flutter - Filter out the display items according to Firebase keys, and in descending order


I am trying to create a Flutter portfolio sorted by "categories" with flat buttons. When one click on the categories, the related projects will be filtered and displayed accordingly, in descending order based on the timestamp.

I have succeeded in displaying the projects in descending order, however have been unable to display my projects by the key value.

Code for the "categories" flat buttons:

class PortfolioCategories extends StatefulWidget {
  @override
  _PortfolioCategoriesState createState() => new _PortfolioCategoriesState();
}

class _PortfolioCategoriesState extends State<PortfolioCategories> {
  void _select(CategoryChoice category) {
    setState(() {
    PortfolioRow.itemBuilder(context, category.categoryIndex);
    });
  }

class CategoryChoice {
  const CategoryChoice({this.category, this.categoryIndex});

  final String category;
  final String categoryIndex; //value of 'category' key in Firebase
}

const List<CategoryChoice> categories = const <CategoryChoice>[
  const CategoryChoice(category: 'ALL', categoryIndex: 'Category_ALL'),
  const CategoryChoice(
      category: 'MULTIMEDIA DESIGN', categoryIndex: 'Category_1'),
  const CategoryChoice(category: 'CURATORIAL', categoryIndex: 'Category_2'),
  const CategoryChoice(category: 'ART', categoryIndex: 'Category_3'),
];

Code for my portfolio:

class PortfolioRow extends StatelessWidget {
  const PortfolioRow({Key key, this.category}) : super(key: key);

  final CategoryChoice category;
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: Firestore.instance
          .collection('portfolio')
          .orderBy('createdAt', descending: true)
          .snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return Text("Loading...");
        return GridView.builder(
            physics: ScrollPhysics(),
            shrinkWrap: true,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
            ),
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, index) =>
            portfolioContainer(context, snapshot.data.documents[index])); //portfolioContainer is the portfolio projects that will be displayed
      },
    );
  }
}

Solution

  • My question could be answered by this: how to use where with orderby in flutter

    And then with:

    .where('category', arrayContainsAny:[category.categoryName]) .orderBy('createdAt', descending: true)

    Regarding the query, I was silly to have tried to allow variables query from different classes. I succeed to query request from FlatButton to portfolioRow() when all the code were all appended as a child in _portfolioCategoriesState() as below:

    class PortfolioCategoriesAndDisplay extends StatefulWidget {
      @override
      _PortfolioCategoriesAndDisplayState createState() =>
          new _PortfolioCategoriesAndDisplayState();
    }
    
    String _showCat = 'All'; //default state is All
    
    class CategoryChoice {
      const CategoryChoice({this.category, this.categoryName});
    
      final String category;
      final String categoryName; //'category.[Name]' in Firebase
    
      @override
      String toString() {
        return 'category: $category categoryName: $categoryName';
      }
    }
    
    const List<CategoryChoice> categories = const <CategoryChoice>[
      const CategoryChoice(categoryName: 'All'),
      const CategoryChoice(categoryName: 'Multimedia Design'),
      const CategoryChoice(categoryName: 'Curatorial'),
      const CategoryChoice(categoryName: 'Sustainability'),
    ];
    
    class _PortfolioCategoriesAndDisplayState
        extends State<PortfolioCategoriesAndDisplay> {
      void _select(String newCategory) {
        setState(() {
          _showCat = newCategory;
        });
      }
    
      Widget build(BuildContext context) {
        return Container(
            child: Row(
          children: [
            Expanded(
              child:
                  Column(children: [
                Container(
                  child:
                      Row(children: [
                    FlatButton(
                        onPressed: () {
                          _select(categories[0].categoryName);
                        },
                        child: Text(
                          'ALL',
                        )),
                    FlatButton(
                        onPressed: () {
                          _select(categories[1].categoryName);
                        },
                        child: Text(
                          'MULTIMEDIA DESIGN',
                        )),
                    FlatButton(
                        onPressed: () {
                          _select(categories[2].categoryName);
                        },
                        child: Text(
                          'CURATORIAL',
                        )),
                    FlatButton(
                        onPressed: () {
                          _select(categories[3].categoryName);
                        },
                        child: Text(
                          'SUSTAINABILITY',
                        )),
                  ]),
                ),
                StreamBuilder(
                  stream: Firestore.instance
                      .collection('portfolio')
                      .where('category', arrayContainsAny: [_showCat])
                      .orderBy('projectOrder', descending: true)
                      .snapshots(),
                  builder: (context, snapshot) {
                    if (!snapshot.hasData) return Text("Loading...");
                    return GridView.builder(
                        physics: ScrollPhysics(),
                        shrinkWrap: true,
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 3,
                          crossAxisSpacing: 70.0,
                          mainAxisSpacing: 70.0,
                          childAspectRatio:
                              MediaQuery.of(context).size.height / 1280,
                        ),
                        itemCount: snapshot.data.documents.length,
                        itemBuilder: (context, index) => portfolioContainer(
                            context, snapshot.data.documents[index]));
                  },
                )
              ]),
            )
          ],
        ));
      }
    }