showing all users images in listview with firebase

Issue

In my app, any user can add an Ad and, in home screen, with all Ads showing up in a list view, I get info of every single Ad from the table of cars in firebase; but I want to show the profile images of this user by sending the user id and getting the image from users table.

My function to get data from firebase:

 Future<DocumentSnapshot> getAdData(String uid)async{
  return await FirebaseFirestore.instance.collection('users').doc(uid).
  get();
}

My homescreen:

import 'package:cargaaaalery/functions.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'globalVar.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  FirebaseAuth auth = FirebaseAuth.instance;
  String? username;
  String? userNumber;
  String? carPrice;
  String? carModel;
  String? description;
  String? urlImage;
  String? carLocation;
  String? carColor;
  QuerySnapshot? cars;
 // DocumentSnapshot? users;
  String? usersImg;
  CarMethods carobj = new CarMethods();
  dynamic carUserId;

  Future<bool?> showDialogForAddingData() async {
    return showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text(
              "post a new AD",
              style: TextStyle(
                  fontSize: 22, fontFamily: "Bebas", letterSpacing: 2),
            ),
            content: SingleChildScrollView(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [

                  TextField(
                    decoration: InputDecoration(hintText: "Enter your number"),
                    onChanged: (val) {
                      userNumber = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  TextField(
                    decoration:
                        InputDecoration(hintText: "Enter your car price"),
                    onChanged: (val) {
                      carPrice = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  TextField(
                    decoration:
                        InputDecoration(hintText: "Enter your car name"),
                    onChanged: (val) {
                      carModel = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  TextField(
                    decoration:
                        InputDecoration(hintText: "Enter your car Color"),
                    onChanged: (val) {
                      carColor = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  TextField(
                    decoration:
                        InputDecoration(hintText: "Enter your car description"),
                    onChanged: (val) {
                      description = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  TextField(
                    decoration:
                        InputDecoration(hintText: "Enter your car Image"),
                    onChanged: (val) {
                      urlImage = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  TextField(
                    decoration:
                        InputDecoration(hintText: "Enter your car Location"),
                    onChanged: (val) {
                      carLocation = val;
                    },
                  ),
                  SizedBox(
                    height: 5,
                  ),
                ],
              ),
            ),
            actions: [
              ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                child: Text("Cancel"),
              ),
              ElevatedButton(
                onPressed: () {
                  Map<String, dynamic> carData = {
                    'username': getUsername,
                    'uId': userId,
                    'userNumber': this.userNumber,
                    'carPrice': this.carPrice,
                    'carModel': this.carModel,
                    'carLocation': this.carLocation,
                    'carColor': this.carColor,
                    'description': this.description,
                    'urlImage': this.urlImage,
                    'imgPro': userImageUrl,
                    'time': DateTime.now(),
                  };
                  carobj.addData(carData).then((value) {
                    print("data add successfuly");
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) {
                      return HomeScreen();
                    }));
                  }).catchError((onError) {
                    print(onError);
                  });
                },
                child: Text("Add Now"),
              ),
            ],
          );
        });
  }
 getimage()async{
  await carobj.getAdData(carUserId).then((res){
     setState(() {
       usersImg=(res.data() as Map)['imgPro'].toString();
     });

   });
}
  getMyData() async {
   await FirebaseFirestore.instance
        .collection('users')
        .doc(userId)
        .get()
        .then((result) {
      setState(() {
        userImageUrl = result.data()!['imgPro'];
        getUsername = result.data()!['username'];

      });
    });
  }

  @override
  void initState() {
    super.initState();
    userId = FirebaseAuth.instance.currentUser!.uid;
    userEmail = FirebaseAuth.instance.currentUser!.email!;
    print("userid is $userId and email is $userEmail");

    carobj.getData().then((results) {
      setState(() {

        cars = results;


      });
    });
    getMyData();

  }

  @override
  Widget build(BuildContext context) {

    Widget? showCarsList() {
      if (cars != null) {


        return ListView.builder(
          itemCount: cars!.docs.length,
          padding: EdgeInsets.all(8),
          itemBuilder: (context,index) {
           carUserId= (cars!.docs[index].data() as Map)['uId'];
            getimage();


            return Card(
              child: Column(
                children: [
                  ListTile(

                    leading:GestureDetector(
                      onTap: (){},
                      child: Container(
                        width: 60,
                        height:60,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          image: DecorationImage(
                            image: NetworkImage(
                                ((usersImg!)),scale: 0.9),
                              fit:BoxFit.fill
                          )
                        ),
                      ),
                    ) ,
                    title: GestureDetector(
                      onTap: (){

                      },
                      child: Text((cars!.docs[index].data() as Map)['username'].toString()),
                    ),
                    subtitle: GestureDetector(
                      onTap: (){},
                      child:
                      Row(
                       children: [
                       ((cars!.docs[index].data() as Map)['carLocation'] != null)
                           ? Text((cars!.docs[index].data() as Map)['carLocation'] ,
                             style:TextStyle(color: Colors.black.withOpacity(0.6))
                            ):Text("unknown" ,
                           style:TextStyle(color: Colors.black.withOpacity(0.6))
                       ),

                        SizedBox(width: 4.0,),
                         Icon(Icons.location_pin,color: Colors.grey,)
                       ],
                      ),
                    ),
                    trailing:
                    (cars!.docs[index].data() as Map)['uId']==userId?
                    Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        GestureDetector(
                          onTap: (){

                          },
                          child: Icon(Icons.edit),
                        ),
                        SizedBox(width: 20,),
                        GestureDetector(
                          onDoubleTap: (){

                          },
                          child: Icon(Icons.delete_forever),
                        ),
                      ],
                    ):
                    Row(  mainAxisSize: MainAxisSize.min,
                      children: [],
                    )
                    ,
                  )
                ],
              ),
            );
          },
        );
      }
    }

    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.refresh, color: Colors.white),
          onPressed: () {},
        ),
        actions: [
          TextButton(
              onPressed: () {},
              child: Padding(
                padding: EdgeInsets.all(10),
                child: Icon(
                  Icons.person,
                  color: Colors.white,
                ),
              )),
          TextButton(
              onPressed: () {},
              child: Padding(
                padding: EdgeInsets.all(10),
                child: Icon(
                  Icons.search,
                  color: Colors.white,
                ),
              )),
          TextButton(
              onPressed: () {},
              child: Padding(
                padding: EdgeInsets.all(10),
                child: Icon(
                  Icons.login_outlined,
                  color: Colors.white,
                ),
              ))
        ],
        flexibleSpace: Container(
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  colors: [Colors.blueAccent, Colors.redAccent])),
        ),
        title: Text("home page"),
      ),
      body: Center(
        child: showCarsList(),
      ),
      floatingActionButton: FloatingActionButton(
        tooltip: 'add post',
        child: Icon(Icons.add),
        onPressed: () {
          showDialogForAddingData();
        },
      ),
    );
  }
}

Where I get image (from home screen code):

getimage()async{
  await carobj.getAdData(carUserId).then((res){
     setState(() {
       usersImg=(res.data() as Map)['imgPro'].toString();
     });

   });
}

Where I set image to listview (from home screen code):

@override
  Widget build(BuildContext context) {

    Widget? showCarsList() {
      if (cars != null) {


        return ListView.builder(
          itemCount: cars!.docs.length,
          padding: EdgeInsets.all(8),
          itemBuilder: (context,index) {
           carUserId= (cars!.docs[index].data() as Map)['uId'];
            getimage();


            return Card(
              child: Column(
                children: [
                  ListTile(

                    leading:GestureDetector(
                      onTap: (){},
                      child: Container(
                        width: 60,
                        height:60,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          image: DecorationImage(
                            image: NetworkImage(
                                ((usersImg!)),scale: 0.9),
                              fit:BoxFit.fill
                          )
                        ),
                      ),
                    ) ,

Output of the code:

output of the code

Solution

You’re getting the behaviour because you are calling setState in the build method. This causes the build method to get called again and it makes the network request and calls the build method again…

You can fix this by using a FutureBuilder to get the data. Follow these steps:

  1. Update the getimage method to return the image url instead of changing the state:
Future<String> getimage() async {
  var res = await carobj.getAdData(carUserId);
  return (res.data() as Map)['imgPro'].toString();
}
  1. Declare a variable _imageFuture to hold the result of the getimage network request:
Future<String> _imageFuture;
  1. Assign the getimage method to _imageFuture in the initState:
@override
  void initState() {
    ...
    _imageFuture = getimage();
}
  1. Update the ListTile to use a FutureBuilder which gets the image from the _imageFuture Future:
ListTile(
  leading:GestureDetector(
    onTap: (){},
    child: FutureBuilder<String>(
      future: _imageFuture,
      builder: (context, AsyncSnapshot<String> snapshot) {
        if (snapshot.data == null) {
          return Center(child: CircularProgressIndicator());
        } else {
          String usersImg = snapshot.data;

          return Container(
            width: 60,
            height:60,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              image: DecorationImage(
                image: NetworkImage(
                  ((usersImg!)),scale: 0.9),
                  fit:BoxFit.fill
                )
              ),
            ),
          );
        }
      }
    ),
  ),
)

Answered By – Victor Eronmosele

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *