Mikael Wills
Mikael Wills

Reputation: 195

StreamProvider returning null too quickly after image saved to firebase storage

I'm adding products to a list and saving an image with each product. To display the image next to each product the image link comes through a StreamProvider.

Just after I add a new product with an image and the Navigator pops back to the list, the image won't show next to the new product, but if i save the project or log out and in again the image now shows. I believe whats happening is that the stream is too quick and is returning a null before the image is properly saved, because after a few seconds i can see the stream stops returning null and returns the proper link for new image (shown from a print() statement).

Im struggling to think of a way to somehow delay the stream or to call an update once the stream is no longer sending a null and is sending the image link.

Widget end:

class _ProductTileState extends State<ProductTile> {
  @override
  Widget build(BuildContext context) {
    var _imageLocation = Provider.of<String>(context);

    return Padding(
      padding: EdgeInsets.only(top: 8.0),
      child: Card(
        margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
        child: ListTile(
          leading: Builder(builder: (context) {
            if (_imageLocation != null) {
              return Image.network(_imageLocation ?? "");
            } else {
              return CircularProgressIndicator();
            }
          }),

StreamProvider initialisation

return Scaffold(
      body: ListView.builder(
        itemCount: products.length,
        itemBuilder: (context, index) {
          return StreamProvider<String>.value(
            initialData: '',
            value: ImageDatabaseService().imageLocation(products[index]),
            catchError: (_, __) => null,
            child: ProductTile(product: products[index]),
          );
        },
      ),

Source of Stream:

class ImageDatabaseService {
  Stream<String> imageLocation(Product product) {
    StorageReference ref = FirebaseStorage.instance
        .ref()
        .child('images/' + product.kaizenID + '.png');
    print("sending, ${product.kaizenID} from ImageDatabaseService");

    return ref.getDownloadURL().asStream().map((downloadUrl) => downloadUrl);
  }
}

Upvotes: 0

Views: 155

Answers (1)

Sergey Salnikov
Sergey Salnikov

Reputation: 1781

You doing all right

You need to consider that the image upload is time taking routine and consist network delay, serverside image processing, etc

There is one right way to live in this world - show progress indication to show user you perform some action (till you receive image link)

Do that and user will be happy

ps do not hesistate to reach me in comments, if you have some additional info regard your question

Upvotes: 1

Related Questions