flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 [cloud_firestore] Can't filter data with collectionGroup

Open edsonISA opened this issue 1 year ago • 5 comments

Bug report

Describe the bug When I use:

collectionGroup('example').where('name', isEqualTo: 'name-to-search')

to be able to filter sub-collections, the data is found but after a few seconds it is lost and starts loading indefinitely

Steps to reproduce

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class CartPage extends StatefulWidget {
  const CartPage({Key? key}) : super(key: key);

  @override
  State<CartPage> createState() => _CartPageState();
}

class _CartPageState extends State<CartPage> {

  TextEditingController searchProduct = TextEditingController();

  @override
  void dispose() {
    searchProduct.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: TextField(
          controller: searchProduct,
          onChanged: (String value) => setState(() {}),
        ),
      ),
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collectionGroup('items')
            .where('name', isEqualTo: searchProduct.text)
            .snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          if (snapshot.hasData) {
            if (snapshot.data!.docs.isEmpty) {
              return const Text('Empty');
            } else {
              return ListView.builder(
                itemCount: snapshot.data!.docs.length,
                itemBuilder: (BuildContext context, int index) {
                  DocumentSnapshot docSnap = snapshot.data!.docs[index];
                  return ListTile(
                    title: Text(docSnap['name']),
                  );
                },
              );
            }
          }
          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

Additional context

This only happens with collectionGroup, because when I use collection to filter only a single collection it works fine


Flutter doctor

Run flutter doctor and paste the output below:

Click To Expand
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.0.5, on Microsoft Windows [Versi¢n 10.0.19042.1288], locale es-ES)
[√] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.11.11)
[√] Android Studio (version 2021.2)
[√] VS Code, 64-bit edition (version 1.69.2)
[√] Connected device (4 available)
[√] HTTP Host Availability

• No issues found!

Flutter dependencies

Run flutter pub deps -- --style=compact and paste the output below:

Click To Expand
Dart SDK 2.17.6
Flutter SDK 3.0.5
keyecommerce 1.0.0+1

dependencies:
- cloud_firestore 3.4.2 [cloud_firestore_platform_interface cloud_firestore_web collection firebase_core firebase_core_platform_interface flutter meta]
- cupertino_icons 1.0.5
- firebase_core 1.20.0 [firebase_core_platform_interface firebase_core_web flutter meta]
- flutter 0.0.0 [characters collection material_color_utilities meta vector_math sky_engine]

dev dependencies:
- flutter_lints 2.0.1 [lints]
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher material_color_utilities meta source_span stream_channel string_scanner term_glyph]

transitive dependencies:
- async 2.8.2 [collection meta]
- boolean_selector 2.1.0 [source_span string_scanner]
- characters 1.2.0
- charcode 1.3.1
- clock 1.1.0
- cloud_firestore_platform_interface 5.7.0 [collection firebase_core flutter meta plugin_platform_interface]
- cloud_firestore_web 2.8.2 [cloud_firestore_platform_interface collection firebase_core firebase_core_web flutter flutter_web_plugins js]
- collection 1.16.0
- fake_async 1.3.0 [clock collection]
- firebase_core_platform_interface 4.5.0 [collection flutter flutter_test meta plugin_platform_interface]
- firebase_core_web 1.7.1 [firebase_core_platform_interface flutter flutter_web_plugins js meta]
- flutter_web_plugins 0.0.0 [flutter js characters collection material_color_utilities meta vector_math]
- js 0.6.4
- lints 2.0.0
- matcher 0.12.11 [stack_trace]
- material_color_utilities 0.1.4
- meta 1.7.0
- path 1.8.1
- plugin_platform_interface 2.1.2 [meta]
- sky_engine 0.0.99
- source_span 1.8.2 [collection path term_glyph]
- stack_trace 1.10.0 [path]
- stream_channel 2.1.0 [async]
- string_scanner 1.1.0 [charcode source_span]
- term_glyph 1.2.0
- test_api 0.4.9 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph matcher]
- vector_math 2.1.2

edsonISA avatar Aug 01 '22 12:08 edsonISA

Thanks for the detailed report.

Have you confirmed that you have set the index properly of your Firestore database for the said collectionGroup ? You can read about it here:

https://firebase.google.com/docs/firestore/query-data/index-overview?authuser=0#automatic_indexing

darshankawar avatar Aug 02 '22 08:08 darshankawar

Gracias por el informe detallado.

¿Ha confirmado que ha configurado correctamente el índice de su base de datos Firestore para dicho collectionGroup? Usted puede leer sobre ello aquí:

https://firebase.google.com/docs/firestore/query-data/index-overview?authuser=0#automatic_indexing

Yes, I can get the data, I can even filter it, but it only shows for a few seconds and then it is lost, showing me the CircularProgressIndicator forever.

In the terminal I get this: W/Firestore(25174): (24.2.1) [WatchStream]: (89de441) Stream closed with status: Status{code=NOT_FOUND, description=Target id not found: 8, cause=null}

edsonISA avatar Aug 03 '22 05:08 edsonISA

Stream closed with status: Status{code=NOT_FOUND, description=Target id not found: 8, cause=null}

NOT_FOUND per FirebaseFirestoreException documentation is thrown when some requested document is not found:

https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/FirebaseFirestoreException.Code#public-static-final-firebasefirestoreexception.code-not_found

Can you confirm that the document under collectionGroup exists and you are able to print those documents before hand before filtering the data ?

darshankawar avatar Aug 03 '22 06:08 darshankawar

@edsonISA

hello,

I suggest:

changing:

class _CartPageState extends State<CartPage> {

  TextEditingController searchProduct = TextEditingController();

to:

TextEditingController searchProduct = TextEditingController();
class _CartPageState extends State<CartPage> {

removing the condition: if (snapshot.hasData) {

and merge it with: if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {

hope it helps,

Thanks.

imeDevelopers avatar Aug 07 '22 14:08 imeDevelopers

this is best version in my opinion:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class CartPage extends StatefulWidget {
  const CartPage({Key? key}) : super(key: key);

  @override
  State<CartPage> createState() => _CartPageState();
}

TextEditingController searchProduct = TextEditingController();
class _CartPageState extends State<CartPage> {

  @override
  void dispose() {
    searchProduct.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: TextField(
          controller: searchProduct,
          onChanged: (String value) => setState(() {}),
        ),
      ),
      body: StreamBuilder(
        stream: FirebaseFirestore.instance.collectionGroup('items').where('name', isEqualTo: searchProduct.text).snapshots(),
        builder:(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
            if(snapshot.hasData||snapshot.data!.docs.isNotEmpty){

              return ListView.builder(
                itemCount: snapshot.data!.docs.length,
                itemBuilder: (BuildContext context, int index) {
                  DocumentSnapshot docSnap = snapshot.data!.docs[index];
                  return ListTile(
                    title: Text(docSnap['name']),
                  );
                },
              );

            }else{return const Text('Empty');}
          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

imeDevelopers avatar Aug 07 '22 14:08 imeDevelopers

Hey @edsonISA. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar Aug 16 '22 01:08 google-oss-bot

Since there haven't been any recent updates here, I am going to close this issue.

@edsonISA if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

google-oss-bot avatar Aug 24 '22 01:08 google-oss-bot