0

I'm experiencing a quite not stable respond in getting my array of data. I'm showing this data in a list of card. I'm saying not stable because everytime I go to another navigation in my app then I'll go back to that nav where I output my data. It shows a red back ground first then for a mil of seconds it shows the data. Anyone know how to fix this? I'm just new in flutter / android. Please help.

For the red background it shows this on terminal and output the data that I'm getting.

The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#dac03):
The getter 'documents' was called on null.
Receiver: null
Tried calling: documents

My code:

StreamBuilder<QuerySnapshot>(
                stream: db.collection('ACTIVITIES').snapshots(),
                builder: (context, snapshot) {
                  final issuesList = snapshot.data.documents
                      .map((doc) => doc['Issue'].map<Widget>((issue) => buildItem(issue)).toList())
                      .toList();
                  return Column(
                      children: issuesList.expand<Widget>((issue) => issue).toList()
                  );
                })

My db structure:

enter image description here

Please Help.

1 Answer 1

1

The problem you're facing is that inside StreamBuilder, snapshot.data is null and then the data arrives. That's why you see the red screen with the error and then it works normally.

First of all, when you use a StreamBuilder you should check if snapshot.data has something and then start using the data. You could use snapshot.hasData, like this:

StreamBuilder<QuerySnapshot>(
  stream: db.collection('ACTIVITIES').snapshots(),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return Column(...);
    }
    return Text('Loading...');
  },
)

With this now you'll see 'Loading...' instead of the red screen with the error, and when the data arrives you'll see the data normally.

Now, when you go to another screen and you come back, the build() method triggers again and the StreamBuilder will get the data from the stream again. Even if Firestore caches the data, it might take a while to be available so you'll get null and then the cached data will arrive. It won't take too long like the first time, but you'll probably see 'Loading...'.

To avoid showing 'Loading...' after the first time you received the data, you could use a memory cache and set that as initialData on the StreamBuilder, like this:

QuerySnapshot cache; // declare this outside build()

StreamBuilder<QuerySnapshot>(
  initialData: cache,
  stream: db.collection('ACTIVITIES').snapshots(),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return Column(...);
    }
    cache = snapshot.data;
    return Text('Loading...');
  },
)

With this I think you could solve your problem. If you want to see more suggestions, check this: How to cache Firebase data in Flutter?

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks again sir @Pablo. Got it working, you're really a life savior!

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.