Nisar ahmed
Nisar ahmed

Reputation: 57

Flutter Firebase Nested Collection help needed

I have created a FireStore with nested collections, now I want to fetch data from it based on some conditions. I tried to create a "Future<List>" and tried to get the data from the collections and store in it, and then returning it in "FutureBuilder". But for some reason my code is working but it is not showing any output.

My Database Structure

Class
     Documents
             ---------------
             course (collection)       
                             Documents
                                     CourseName                                   
                                     Slot
                                     TeacherId
             ---------------
             ClassId
             ClassName

My Code to fetch the data from collection

Future<List<Teaching>> findTeachingCourses(String documnentId) async {
    Future<List<Teaching>> teachingList = Future<List<Teaching>>.delayed(
      Duration(seconds: 0),
      () {
        Future<QuerySnapshot> result = classCollection.getDocuments();
        List<Teaching> list = new List<Teaching>();

        result.then(
          (value) => value.documents.forEach(
            (element) {
              Future<QuerySnapshot> result2 = classCollection
                  .document(element.documentID)
                  .collection("course")
                  .getDocuments();

              result2.then(
                (value2) => value2.documents.forEach(
                  (element2) {
                    //print(element.data);
                    //print(element2.data);

                    Stream<DocumentSnapshot> result3 =
                        collection.document(documnentId).get().asStream();

                    result3.forEach((element3) {
                      if (element3.data["id"] == element2.data["teacherId"]) {
                        Courses course = Courses(element2.data["courseName"],
                            element2.data["slot"], element2.data["teacherId"]);

                        Teaching teaching =
                            Teaching(course, element.data["classid"]);
                        list.add(teaching);

                        print(course.toJson());
                        print(element3.data["id"]);
                      }
                    });
                  },
                ),
              );
            },
          ),
        );
        return list;
      },
    );

    return teachingList;
  }

Builder Code

child: FutureBuilder<List<Teaching>>(
          future: repository.findTeachingCourses(_CurrentUser.documentId),
          builder: (context, snapshot) {
            if (snapshot.connectionState != ConnectionState.done) {
              //return showLoaderDialog(context);
              print("show loading dialog");
            }

            List<Teaching> list = snapshot.data ?? [];

            return ListView.builder(
              itemCount: list.length,
              itemBuilder: (context, index) {
                Teaching teaching = list[index];
                return Card(
                  child: Padding(
                    padding: const EdgeInsets.all(8),
                    child: Column(
                      children: <Widget>[
                        Text("Class ID : " + teaching.classid.toString()),
                        Text("Course : " + teaching.course.courseName),
                      ],
                    ),
                  ),
                );
              },
            );
          },
        ),

The code is running without giving me any errors, but I am not getting any output. Any suggestions please?

Upvotes: 0

Views: 2082

Answers (1)

dshukertjr
dshukertjr

Reputation: 18750

This is not a complete solution at all, but hopefully will give you idea of how you might be able to organize your code a bit.

Basically, you can use await instead of then to remove your code being wrapped into multiple layers of parenthesis. You should also consider giving variable more meaningful names!

Below is my attempt to rewrite your code, but I failed to complete it after finding out I do not know what collection variable is in your code.

 Future<List<Teaching>> findTeachingCourses(String documnentId) async {
    // This would be result
    final QuerySnapshot classesSnapshot = await classCollection.get();

    // This would be result2 combined in a single List
    final List<Future<QuerySnapshot>> coursesFuture = classesSnapshot.docs
        .map((classDoc) =>
            classCollection.doc(classDoc.id).collection("course").get())
        .toList();

    // This would be element2 combined in a single List
    final List<QuerySnapshot> coursesSnapshotList =
        await Future.wait(coursesFuture);

    // This would be element3
    final DocumentSnapshot targetSnapshot =
        await classCollection.doc(documnentId).get();
    }

Upvotes: 2

Related Questions