title: CachedNetworkImage only shows placeholder and doesn't load image in Flutter chat app
body: <p>First of all, I am a complete beginner (not only in dart/flutter), but in programming in general. I am currently working on a chat app.</p>
  
  <p><strong>Goal:</strong> When I am picking an image within the ChatScreen - analog to e.g. WhatsApp - it should immediately appear as a message (placeholder with loading symbol, while it is uploaded to Firestore).</p>
  
  <p><strong>Problem:</strong> Everything is working fine, but here is one issue: When I am picking an image via the imagepicker, it get's uploaded but there's a delay until it is displayed as a message in the chat. imagepicker -> write to Firestore -> Streambuilder
   (listView.builder).</p>
  
  <p><strong>My attempt:</strong> I am using CachedNetworkImage, but unfortunately, it keep's showing the placeholder (CircularProgressIndicator), but not the actual image. If I am just displaying the image, everything works fine (besides the delay). </p>
  
  <p>Moreover, I would highly appreciate some ideas to make the app run faster / improve the code ;-).</p>
  
  <pre><code>//Chat screen which lists all the chat messages, including _handleSubmitted and the _buildTextComposer
  
  import 'dart:math';
  import 'dart:io';
  
  import 'package:flutter/cupertino.dart';
  import 'package:flutter/foundation.dart';
  import 'package:flutter/material.dart';
  import 'package:image_picker/image_picker.dart';
  import 'package:firebase_storage/firebase_storage.dart';
  import 'package:cloud_firestore/cloud_firestore.dart';
  import 'package:firebase_database/firebase_database.dart';
  import 'package:intl/intl.dart';
  import 'package:fluttertoast/fluttertoast.dart';
  import 'package:cached_network_image/cached_network_image.dart';
  import 'package:transparent_image/transparent_image.dart';
  import 'package:flutter_image/network.dart';
  import 'package:flutter_native_image/flutter_native_image.dart';
  
  final database = Firestore.instance
      .collection('nachrichten')
      .document('G5xlQHvb56ZqpWs7ojUV');
  final reference = FirebaseDatabase.instance.reference().child('messages');
  
  class ChatScreen extends StatefulWidget {
    @override
    State createState() =&gt; new ChatScreenState();
  }
  
  class ChatScreenState extends State&lt;ChatScreen&gt; with TickerProviderStateMixin {
    final TextEditingController _textController = new TextEditingController();
    final ScrollController _scrollController = new ScrollController();
  
    bool _isComposing = false;
    bool isLoading;
    String imageUrl;
    File imageFile;
  
    //optional from other code
    @override
    void initState() {
      super.initState();
      imageUrl = '';
    }
  
    Future getImage() async {
      imageFile = await ImagePicker.pickImage(source: ImageSource.camera);
  
      if (imageFile != null) {
        setState(() {
          isLoading = true;
        });
        uploadFile();
      }
    }
  
    Future uploadFile() async {
      //file compression
      File compressedFile = await FlutterNativeImage.compressImage(imageFile.path,
          quality: 100, percentage: 100);
      String fileName = DateTime.now().millisecondsSinceEpoch.toString();
      StorageReference reference = FirebaseStorage.instance.ref().child(fileName);
      StorageUploadTask uploadTask = reference.putFile(compressedFile);
      StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
      storageTaskSnapshot.ref.getDownloadURL().then((downloadUrl) {
        imageUrl = downloadUrl;
        setState(() {
          isLoading = false;
          _handleSubmitted(imageUrl: imageUrl);
        });
      }, onError: (err) {
        setState(() {
          isLoading = false;
        });
        Fluttertoast.showToast(msg: 'This file is not an image');
      });
    }
  
    //Builds the button text composer, including camera icon, text input and send button
    Widget _buildTextComposer() {
      return new IconTheme(
        data: new IconThemeData(color: Theme.of(context).accentColor),
        child: new Container(
            margin: const EdgeInsets.symmetric(horizontal: 0.80),
            child: new Row(children: &lt;Widget&gt;[
              new Container(
                margin: new EdgeInsets.symmetric(horizontal: 0.4),
                child: new IconButton(
                  icon: new Icon(Icons.photo_camera),
                  onPressed: getImage,
                ),
              ),
              new Flexible(
                child: Container(
                  margin: const EdgeInsets.symmetric(vertical: 10.0),
                  padding: EdgeInsets.all(10.0),
                  decoration: new BoxDecoration(
                    border: Border.all(color: Colors.grey.shade200),
                    borderRadius: new BorderRadius.circular(20.0),
                  ),
  
                  //container with constraint limits the maximum height of the text input field
                  child: new Container(
                    constraints: BoxConstraints.loose(Size.fromHeight(100.0)),
                    child: new TextField(
                      maxLines: null,
                      keyboardType: TextInputType.multiline,
                      controller: _textController,
                      onChanged: (String text) {
                        setState(() {
                          _isComposing = text.length &gt; 0;
                        });
                      },
  //                    onSubmitted: _handleSubmitted,
                      decoration: new InputDecoration.collapsed(
                          hintText: "Nachricht schreiben..."),
                    ),
                  ),
                ),
              ),
              new Container(
                  margin: new EdgeInsets.symmetric(horizontal: 0.4),
                  child: Theme.of(context).platform == TargetPlatform.iOS
                      ? new CupertinoButton(
                          child: new Text("Send"),
                          onPressed: _isComposing
                              ? () =&gt; _handleSubmitted(text: _textController.text)
                              : null,
                        )
                      : new IconButton(
                          icon: new Icon(Icons.send),
                          onPressed: _isComposing
                              ? () =&gt; _handleSubmitted(text: _textController.text)
                              : null,
                        )),
            ]),
            decoration: Theme.of(context).platform == TargetPlatform.iOS
                ? new BoxDecoration(
                    border:
                        new Border(top: new BorderSide(color: Colors.grey[200])))
                : null),
      );
    }
  
    //Builds the actual chat screen with Scaffold
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
            title: new Text("Chat.here Gruppenchat"),
            centerTitle: true,
            elevation:
                Theme.of(context).platform == TargetPlatform.iOS ? 0.0 : 4.0),
        body: StreamBuilder&lt;QuerySnapshot&gt;(
            stream: Firestore.instance
                .collection('nachrichten')
                .orderBy('timestamp', descending: true)
                .limit(20)
                .snapshots(),
            builder:
                (BuildContext context, AsyncSnapshot&lt;QuerySnapshot&gt; snapshot) {
              if (!snapshot.hasData) return Text('Loading data');
              final int documentsLength = snapshot.data.documents.length;
              return Container(
                  child: Column(
                    children: &lt;Widget&gt;[
                      new Flexible(
                          child: new ListView.builder(
                        controller: _scrollController,
                        reverse: true,
                        itemCount: documentsLength,
                        itemBuilder: (context, int index) {
                          final DocumentSnapshot document =
                              snapshot.data.documents[index];
                          return new Container(
                            margin: const EdgeInsets.symmetric(
                                horizontal: 10.0, vertical: 10.0),
                            child: new Row(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: &lt;Widget&gt;[
                                new Container(
                                  margin: const EdgeInsets.only(right: 16.0),
                                  child: new CircleAvatar(
                                      child: new Text(
                                          document['author'].substring(0, 1))),
                                ),
                                new Expanded(
                                  child: new Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: &lt;Widget&gt;[
                                      new Row(
                                        children: &lt;Widget&gt;[
                                          new Text(document['author'],
                                              style: TextStyle(
                                                  fontSize: 12.0,
                                                  color: Colors.black45,
                                                  fontWeight: FontWeight.bold)),
                                          new Text(
                                              ' ' +
                                                  DateFormat("MMM. d. '|' HH:mm")
                                                      .format(
                                                          document['timestamp']),
                                              style: TextStyle(
                                                  fontSize: 12.0,
                                                  color: Colors.black45))
                                        ],
                                      ),
  
                                      //can be deleted. just to test the picture.
                                      (document['text'] == null)
                                          ? new Container(
                                              child: new ClipRRect(
                                                borderRadius:
                                                    new BorderRadius.circular(
                                                        7.0),
                                                child: CachedNetworkImage(
                                                  placeholder: Container(
                                                    child:
                                                        CircularProgressIndicator(
                                                      valueColor:
                                                          AlwaysStoppedAnimation&lt;
                                                                  Color&gt;(
                                                              Colors.orange),
                                                    ),
                                                    width: 200.0,
                                                    height: 200.0,
                                                    padding: EdgeInsets.all(70.0),
                                                    decoration: BoxDecoration(
                                                      color: Colors.blue,
                                                      borderRadius:
                                                          BorderRadius.all(
                                                        Radius.circular(8.0),
                                                      ),
                                                    ),
                                                  ),
                                                  imageUrl:
                                                      'https://wuppertal-total.de/wp-content/uploads/2019/01/stamp_schmidt_fdp.jpg',
                                                  width: 200.0,
                                                  height: 200.0,
                                                  fit: BoxFit.cover,
                                                ),
  
  
                                              ),
                                              margin:
                                                  EdgeInsets.only(right: 50.0),
                                            )
  
                                          : new Card(
                                              margin:
                                                  EdgeInsets.only(right: 50.0),
                                              //green color for messages of yourself
                                              color:
                                                  document['author'] == "Matthias"
                                                      ? Color.fromRGBO(
                                                          220, 255, 202, 1.0)
                                                      : null,
                                              child: new Container(
                                                  padding: EdgeInsets.all(6.0),
                                                  child: new Text(
                                                    document['text'],
                                                    style:
                                                        TextStyle(fontSize: 15.0),
                                                  )),
                                              shape: RoundedRectangleBorder(
                                                  borderRadius:
                                                      BorderRadius.circular(7.0)),
                                            ),
  
                                    ],
                                  ),
                                ),
                              ],
                            ),
                          );
                        },
                      )),
                      new Divider(height: 1.0),
                      new Container(
                        decoration:
                            new BoxDecoration(color: Theme.of(context).cardColor),
                        child: _buildTextComposer(),
                      ),
                    ],
                  ),
                  decoration: Theme.of(context).platform == TargetPlatform.iOS
                      ? new BoxDecoration(
                          border: new Border(
                              top: new BorderSide(color: Colors.grey[200])))
                      : null);
            }),
      );
    }
  
  
    void _handleSubmitted({String text, String imageUrl}) {
      _textController.clear();
      setState(() {
        _isComposing = false;
      });
  
      //creation of an own document in Firestore
      Firestore.instance.runTransaction((Transaction transaction) async {
        CollectionReference reference =
            Firestore.instance.collection('nachrichten');
  
        await reference.add({
          "text": text,
          "author": "Matthias",
          "imageUrl": imageUrl,
          "timestamp": DateTime.now(),
  
          //"timestamp": FieldValue.serverTimestamp()
        });
      });
  
  //Let the chat list jump to the newest chat message at the bottom
      _scrollController.animateTo(
        0.0,
        curve: Curves.easeOut,
        duration: const Duration(milliseconds: 300),
      );
    }
  
  }
  </code></pre>