SK1dev
SK1dev

Reputation: 1139

Filtering data from Firebase Firestore

I have a field in a document named 'category' and within 'category' I have 6 different types of values(1-6). I want to display documents for each value on different screens. So all 'category' fields with the value of say 2, for example, should be displayed on screen 2. How would I get this to work?

Widget build(BuildContext context) {
    return FutureBuilder(
        future: FirebaseAuth.instance.currentUser(),
        builder: (ctx, futureSnapshot) {
          if (futureSnapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: const CircularProgressIndicator(),
            );
          }
          return StreamBuilder(
              stream: Firestore.instance
              .collection('facts')
              .orderBy('category')
              .where('category', isEqualTo: '1')
              .where('category', isEqualTo: '2')
              .where('category', isEqualTo: '3')
              .where('category', isEqualTo: '4')
              .where('category', isEqualTo: '5')
              .where('category', isEqualTo: '6')
              .snapshots(),

              builder: (ctx, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return Center(
                    child: CircularProgressIndicator(
                      valueColor: AlwaysStoppedAnimation<Color>(
                        Theme.of(context).colorScheme.deepOrange,
                      ),
                    ),
                  );
                }

                final factsDocs = snapshot.data.documents;
                return Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: AssetImage("assets/facts_bg.jpg"),
                      fit: BoxFit.cover,
                    ),
                  ),
                  child: Scaffold(
                    backgroundColor: Colors.transparent,
                    body: ListView.builder(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 10, vertical: 10),
                      itemCount: factsDocs.length,
                      itemBuilder: (ctx, index) =>
                          _factsList(context, factsDocs[index]),
                    ),
                  ),
                );
              });
        });
  }

  Widget _factsList(BuildContext context, DocumentSnapshot document) {
    return Container(
      child: Card(
        margin: const EdgeInsets.only(bottom: 16),
        elevation: 6,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        color: Colors.white.withOpacity(0.9),
        child: Column(
          children: [
            Column(
              children: [
                Container(
                  width: MediaQuery.of(context).size.width,
                  height: 120,
                  child: Column(
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(top: 8),
                        child: ListTile(
                          title: Container(
                            child: Text(
                              document['title'] == null
                                  ? ''
                                  : document['title'],
                              style: whiteH1Txt,
                            ),
                          ),
                          subtitle: Padding(
                            padding: const EdgeInsets.only(top: 8),
                            child: Text(
                              document['category'] == null
                                  ? ''
                                  : document['category'],
                              style: whiteSubTxt,
                            ),
                          ),

Upvotes: 0

Views: 787

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317322

The way you are doing this query:

stream: Firestore.instance
    .collection('facts')
    .orderBy('category')
    .where('category', isEqualTo: '1')
    .where('category', isEqualTo: '2')
    .where('category', isEqualTo: '3')
    .where('category', isEqualTo: '4')
    .where('category', isEqualTo: '5')
    .where('category', isEqualTo: '6')

is guaranteed to return 0 documents. Firestore queries apply a logical AND to each where clause. What this query is doing is asking for documents where category is 1 AND 2 AND 3, etc, which you can see is impossible.

If you want a logical OR that includes each category, you can use an whereIn query instead:

stream: Firestore.instance
    .collection('facts')
    .orderBy('category')
    .where('category', whereIn: ['1', '2', '3', '4', '5', '6'])

Your code will have to look at each document to see which category it came from and decide what to do with it.

Upvotes: 1

Related Questions