1

I am trying to pull favicons dynamically and place them as a leading icon in ListTiles which make up a ListView, which is all contained inside a StreamBuilder. The StreamBuilder 'stream' variable is a FirebaseFirestore instance shown below:

streamBuilder = StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('users').doc(snapshot.data.uid).collection('vault').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> querySnapShot){

So the stream is updated every time the snapshot is updated. The snapshot contains docs which are iterated through in a for loop to populate each listtile in the listview. Each doc contains a url. I need to use that 'url' to retrieve that Listtile's respective favicon icon.

import 'package:favicon/favicon.dart' as iconz;

for (var doc in querySnapShot.data.docs) {
   String urlIcon = doc['urlIcon'];
   iconUse = iconz.Favicon.getBest(urlIcon);
leading: iconUse,
title:...

The problem is that the getBest() function returns a future. i.e. Using 'await' for my favicon getBest() function is not allowed inside the StreamBuilder, and my StreamBuilder is already dependent upon the snapshot stream. How do I use an additional Future inside of a StreamBuilder that is already dependent upon a different stream?

metamonkey
  • 427
  • 7
  • 33
  • Can you make your `StreamBuilder` wait on a `Stream` that wraps the original `Stream` and does your additional asynchronous work before emitting each element? – jamesdlin Apr 07 '21 at 23:05

1 Answers1

1

You can use a FutureBuilder for leading: iconUse

import 'package:favicon/favicon.dart' as iconz;

for (var doc in querySnapShot.data.docs) {
   String urlIcon = doc['urlIcon'];
   //iconUse = iconz.Favicon.getBest(urlIcon);
   leading: FutureBuilder(
   future: iconz.Favicon.getBest(urlIcon),
   builder: (context, snapshot2) {
      if (snapshot2.hasData) {
          return snapshot2.data; //or whatever object you want to return from your function.
      } 
    ),

 title:...
Huthaifa Muayyad
  • 11,321
  • 3
  • 17
  • 49
  • Interesting. I will look into this shortly. What I really need is the object returned from iconz.Favicon.getBest(urlIcon). What is the relevance of the if (snapshot2.hasData) { return snapshot2.data; //or whatever object you want to return from your function. } part? – metamonkey Apr 07 '21 at 21:15
  • It'll return your object of interest when the Future is done – Huthaifa Muayyad Apr 07 '21 at 21:21
  • Have you tried it? It should work,updates please – Huthaifa Muayyad Apr 08 '21 at 18:57
  • My apologies for the delay. So, in the case you provided above, snapshot2.data would contain the result of iconz.Favicon.getBest(urlIcon)? – metamonkey Apr 08 '21 at 19:13
  • correct, it's actually the `data` part. `data` is what your function returns, and used `snapshot2` to avoid confusion from `snapshot ` in parent streambuilder above. – Huthaifa Muayyad Apr 08 '21 at 19:15
  • Yes, that works! Thank you for clearing that up for me. – metamonkey Apr 08 '21 at 19:56
  • I created a new question related to this one but a different issue. Got any thoughts? @https://stackoverflow.com/questions/67028311/how-to-cache-a-future-string-in-flutter – metamonkey Apr 09 '21 at 21:10