0

I am starting my first Firebase project with flutter and want to retrieve data from my Firebase CloudFirestore database and display it in the application.

I am getting the data from Firebase with this class:

class getFirebaseData
{
  List<ArticleItems> requestedItems = [];

  Future<List<ArticleItems>> getFirebaseArticles()
  {

    //Create new Firebase instance
    final firestoreInstance = FirebaseFirestore.instance;

    //Get data from Firebase
    firestoreInstance.collection("categories/politik/articles").snapshots().listen((data) =>
    //For each found document run loop
      data.docs.forEach((doc) {

        //Convert Firebase timestamp to DateTime
        Timestamp firebaseTimestamp = doc.data()['articlePublishTimestamp'];
        DateTime firebaseDateTime = DateTime.fromMicrosecondsSinceEpoch(firebaseTimestamp.microsecondsSinceEpoch);

        //Create new ArticleItem and insert data from Firebase
        ArticleItems firebaseItem = new ArticleItems(
            article_id: doc.data()['articleId'],
            article_thumbnail_url: doc.data()['articleThumbnailUrl'],
            article_headline: doc.data()['articleHeadline'],
            article_fulltext: doc.data()['articleFulltext'],
            article_author: doc.data()['articleAuthor'],
            article_category: doc.data()['articleCategory'],
            article_publish_timestamp: firebaseDateTime
        );

        //Add created item to list of all requested items
        requestedItems.add(firebaseItem);

        print('Future finished');
      }));

    }
}

In my main method I am trying to await the result of the request and want to output it (tried to get only the length first to check if there are entries in the list). I used this code for that:

  //Async request to get Firebase Data
  void getArticleInformation() async
  {
    getFirebaseData firebaseData = getFirebaseData();
    await firebaseData.getFirebaseArticles();

    print('Await finished');

    articleItems = firebaseData.requestedItems;
    print("Length FirebaseItems: " + firebaseData.requestedItems.length.toString());
    print("Length ArticleItems: " + articleItems.length.toString());
  }

When I am running the application the length of the returned list is zero (should be 2) and the console output "Await finished" appears before the output "Future finished". To me it seems like the await function is not waiting for the result and just starting to progress the next lines of code.

It would be great if you can show me what I did wrong there and how to fix it.

0

1 Answer 1

1

(I did not test this code.. if somethings wrong or not working tell me :)

You could try somethong like this, looks much cleaner:

class FirebaseRepository {
  Future<List<ArticleItems>> getArticleItems() {
    var instance = Firestore.instance();
    var snapshot = await instance.collection("categories/politik/articles").get();
    return snapshot.docs.map((e)=>ArticleItem.fromSnapshot(e)).toList();
  }

}

And in your ArticleItem like this:

class ArticleItem {

  factory ArticleItem.fromSnapshot(QueryDocumentSnapshot snapshot) {
    return ArticleItem(
      article_id: snapshot.get("articleId"),
      article_thumbnail_url: snapshot.get("articleThumbnailUrl"),
      article_headline: snapshot.get("articleHeadline"),
      article_fulltext: snapshot.get("articleFulltext"),
      article_author: snapshot.get("articleAuthor"),
      article_category: snapshot.get("articleCategory"),
      article_publish_timestamp: firebaseDateTime
    );
  }
}

Retrieve the items like this:

articleItems = await new FirebaseRepository().getArticleItems();
Sign up to request clarification or add additional context in comments.

2 Comments

Hello, thanks for your help. I didn't really get the second part with the class ArticleItems. Can you explain this part in a bit more detail? The class I am using to store the article is called "ArticleItems". Do you want me to create another class in the same file or how exactly should it work? When I am trying to create the class you wrote down there I get an error on return ArticleItem: The class 'ArticleItem' doesn't have a default constructor. Hope you can help with that.
Oh I thought it would be your class. For me it is just best practice to create a "fromSnapshot" method, which extracts all the necessary information to create the object. Of course you could implement a custom method to do it, or just write it directly in the "map" Method

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.