3

Hi i am trying to get data from firestore and populate listview, following is my code, but i am getting exception since my async call is not complete how can i wait for that asyn call to get completed and populate my listview my code is below:

    import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:test_flutter/pkg/Feed.dart';

class FeedLoader {
  final CollectionReference _colReference;

  FeedLoader(Firestore _firestore)
      : _colReference = _firestore.collection(Feed.getDocumentName()) {}

  Future<List<Feed>> load() async {
    final List<Feed> feeds = new List<Feed>();
    await for (QuerySnapshot qs in _colReference.snapshots) {
      for (DocumentSnapshot ds in qs.documents) {
        feeds.add(Feed.fromJson(ds.data));
      }
      return feeds;
    }
    return feeds;
  }
}

This is my Widget

    import 'package:flutter/material.dart';
import 'package:test_flutter/pkg/FeedLoader.dart';
import 'package:test_flutter/pkg/Feed.dart';

class FeedWidget extends StatefulWidget {
  final FeedLoader feedLoader;

  const FeedWidget({Key key, this.feedLoader}) : super(key: key);

  createState() => new FeedWidgetState(feedLoader);
}

class FeedWidgetState extends State<FeedWidget> {
  final List<Feed> _feeds = new List<Feed>();
  final FeedLoader _feedLoader;
  final TextStyle fontStyle = const TextStyle(fontSize: 16.0);

  FeedWidgetState(this._feedLoader);

  @override
  Widget build(BuildContext context) {
    print(_feedLoader == null);
    _feedLoader
        .load()
        .then((feeds) => () {
              print("Got call back now");
              _feeds.addAll(feeds);
            })
        .catchError((e) => handleError(e));

    print("Feeds size ${_feeds}");
    return _buildListView(context);
  }

  void handleError(e) {
    print("FeedLoaderException ${e}");
  }

  Widget _buildListView(BuildContext context) {
    return new ListView.builder(
      padding: const EdgeInsets.all(6.0),
      itemBuilder: (context, i) {
        if (i.isOdd) return new Divider();

        final index = i ~/ 2;
//        pagination
//        if (index >= contents.length) {
//          contents.addAll(generateWordPairs().take(10));
//        }
        return _buildRowContent(context, _feeds[i]);
      },
    );
  }

  Widget _buildRowContent(BuildContext context, Feed content) {
    return new ListTile(
      title: new Text(
        "${content.getTitle()}",
        style: fontStyle,
      ),
    );
  }
}

1 Answer 1

4

You can use StreamBuilder and FutureBuilder to build widgets asynchronously

You could for example do

return new StreamBuilder(
   stream: Firestore....snapshot,
   builder: (context, snapshot) {
      if (snapshot.hasData) {
         final feeds = snapshot.data.map(Feed.fromJson);
         return new ListView(
              ....
         );
      }
   },
)
Sign up to request clarification or add additional context in comments.

3 Comments

It works but i am not able to display data as snapshot.hasData first is false then i return empty Container but it doesnt replace when it has data, i know it a separate question can you help though
If the firestore request was for a single document, would FutureBuilder be preferable, since a stream is not expected?
Stream has nothing to do with multi documents. It's about document update. FirebaseDatabase and Firestore SDK both allow realtime reading ; which translates into stream in dart

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.