Rajdeep
Rajdeep

Reputation: 2462

Future builder is not getting data

I'm using a FutureBuilder in my code in order to query Firestore but I keep getting no data from the function I specified in the FutureBuilder. But funny enough the function is executing and getting the data. It is just not passing it to the FutureBuilder.

Code:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:garuda_academy_app/Tools/FixedColors.dart';

class CoursePage extends StatefulWidget {
  CoursePage({this.userEmail});
  final String userEmail;
  @override
  _CoursePageState createState() => _CoursePageState();
}

class _CoursePageState extends State<CoursePage> {
  @override
  void initState() {
    super.initState();
  }

  Future<List<DocumentSnapshot>> _getCourses() async {
    List<DocumentSnapshot> userCourses = [];

    await Firestore.instance
        .collection("Users")
        .document(widget.userEmail)
        .get()
        .then((DocumentSnapshot userDetails) {
      List<dynamic> courses = userDetails["Courses"];
      courses.forEach((dynamic course) {
        Firestore.instance
            .collection("Courses")
            .document(course)
            .get()
            .then((DocumentSnapshot courseDetails) {
          userCourses.add(courseDetails);

          print(userCourses.length);
        });
      });
    });

    return userCourses;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: secondaryColor,
      resizeToAvoidBottomInset: false,
      body: FutureBuilder(
        future: _getCourses(),
        builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
          // loading display
          if (snapshot.hasError ||
              (snapshot.connectionState == ConnectionState.waiting)) {
            if (snapshot.hasError) print('${snapshot.error}');
            return Center(
              child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(primaryColor),
              ),
            );
          }

          print(snapshot.data.length);

          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (context, index) {
              return Text(
                snapshot.data[index].documentID,
                style: TextStyle(color: Colors.black),
              );
            },
          );
        },
      ),
    );
  }
}

Notice I print the data length twice to check if I am getting anything, the output is as such:

0 // the future print
1 // the function print

It seems like await is not functioning as it should as the future seems to take the List before await.

Does anyone know why this is happening ?

Upvotes: 0

Views: 6861

Answers (2)

Argel Bejarano
Argel Bejarano

Reputation: 622

The Firestore instances needs to be call from a StreamBuilder not FutureBuilder you can se this page from Flutter docs about this widget.

this is the example the team have:

StreamBuilder<int>(
  stream: _lot?.bids, // a Stream<int> or null
  builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
    if (snapshot.hasError)
      return Text('Error: ${snapshot.error}');
    switch (snapshot.connectionState) {
      case ConnectionState.none: return Text('Select lot');
      case ConnectionState.waiting: return Text('Awaiting bids...');
      case ConnectionState.active: return Text('\$${snapshot.data}');
      case ConnectionState.done: return Text('\$${snapshot.data} (closed)');
    }
    return null; // unreachable
  },
)

Upvotes: 0

MSARKrish
MSARKrish

Reputation: 4094

Problem is you are calling async method in inside FutureBuilder Widget. call that function inside initState method and get that return value in one varible and use that in FutureBuilder Widget.

Check this link for more understanding

Similar Problem

Future<List<DocumentSnapshot>> _course;

void initState()
{
    super.initState();
    course= _getCourses()
}

use course variable in FutureBuilder Widget

FutureBuilder(
    future: _course,
    builder: write your code)

Upvotes: 2

Related Questions