Search code examples
flutterdartflutterflowdart-pdf

Looping through Firestore Documents to Display Elements


I'm attempting to loop through a list of documents from Firestore passed to a custom action in Flutterflow and display images according to the photo_url field contained in each document. I'm able to loop through and display strings from the document list, but images are where I'm having trouble.

I've tried including the images in the loop itself, using networkImage as per the "pdf" documentation on "https://pub.dev/packages/pdf", but ran into async/await issues as it was inside the "build" function. So I then placed a second loop at the beginning of my function to populate a list of images to be added to the pdf later during the loop in the build function, but the action fails when I attempt to use networkImage.

Loop:

final doc_imgs = [];
  for (final doc in docs) {
    if (doc.photoUrl.isNotEmpty) {
      final img = await networkImage(doc.photoUrl);
      doc_imgs.add(img);
    }
  }

Update: After further testing, networkImage works with other URLs, just not the ones passed by Firestore.


Solution

  • It looks like you're running into issues with displaying images from Firestore URLs using the networkImage function. Since you mentioned that the function works with other URLs but not with the ones retrieved from Firestore, there are a few things you can check and try to fix the problem:

    1. URL Format Validation:

    • Ensure that the URLs stored in Firestore are valid and properly formatted. Sometimes, extra spaces or special characters can cause issues.
    • You can print out the URLs using print(doc.photoUrl) to see if there are any discrepancies.

    2. Firestore Storage Rules:

    • If your images are stored in Firebase Storage, make sure the storage rules allow read access to the URLs you're trying to fetch. If the rules are too restrictive (e.g., requiring authentication), the images won't load.
    • Try accessing one of the URLs directly in a browser to check if it's accessible.

    3. CORS Issue:

    • If the images are hosted in a different domain or server, there could be CORS (Cross-Origin Resource Sharing) issues. Firebase Storage, for example, sometimes needs CORS headers configured to allow images to be loaded into other domains.
    • You can set up CORS for Firebase Storage with a JSON file like this:
      [
        {
          "origin": ["*"],
          "method": ["GET"],
          "maxAgeSeconds": 3600
        }
      ]
      
      Use the Firebase CLI to deploy it:
      gsutil cors set cors.json gs://your-bucket-name
      

    4. Async Handling in build:

    • Since Flutter doesn't allow async in the build function, you could try pre-fetching the images using a FutureBuilder or similar technique. For example:
      Future<Uint8List> fetchImage(String url) async {
        final response = await http.get(Uri.parse(url));
        return response.bodyBytes;
      }
      
      FutureBuilder<Uint8List>(
        future: fetchImage(doc.photoUrl),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return Image.memory(snapshot.data);
          } else {
            return CircularProgressIndicator();
          }
        },
      );
      

    5. Alternative Image Loading:

    • You can also try using CachedNetworkImage instead of networkImage, as it handles caching and provides more flexibility:
      CachedNetworkImage(
        imageUrl: doc.photoUrl,
        placeholder: (context, url) => CircularProgressIndicator(),
        errorWidget: (context, url, error) => Icon(Icons.error),
      );