Home > Software engineering >  Firestore how to fetch specific data with specific user id in Flutter
Firestore how to fetch specific data with specific user id in Flutter

Time:06-03

I have stream builder, and I fetch all the users. After that, using bloc (or any state management) I filter them. After filtering, I create a Set which has filtered user ids (I mean there is a set, and it has user ids).

Now, using with these uids I want to fetch filtered user datas. I did with FirebaseFirestore.instance.collection(...).doc(userId).get(), after that it gives Future<String?>. What should I do?

here is the codes:

class HomePageBody extends StatelessWidget {
  HomePageBody({
    Key? key,
    required this.mapsState,
  }) : super(key: key);

  final MapsState mapsState;

  final Set users = {};
  @override
  Widget build(BuildContext context) {

    return StreamBuilder<QuerySnapshot>(
      stream: firestoreStream,
      builder: (context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting || snapshot.connectionState == ConnectionState.none) {
          return const CustomProgressIndicator(
            progressIndicatorColor: blackColor,
          );
        } else if (!snapshot.hasData) {
          return const CustomProgressIndicator(
            progressIndicatorColor: blackColor,
          );
        } else if (snapshot.hasData) {
          final usersDatas = snapshot.data.docs;

          for (var userDatas in usersDatas) {
            if (userDatas["latitude"] == null || userDatas["longitude"] == null) {
            } else {
              users.add(userDatas);
            }
          }
          context.read<MapsCubit>().filterUsersWithRespectToDistance(users: users);
          final usersWithInTenKilometers = mapsState.usersWithInTenKilometers;

          **// HERE WE HAVE FILTERED USERS, AND THIS SET HAS USER IDS.**

          return ListView.builder(
                  padding: const EdgeInsets.only(top: 75),
                  itemCount: usersWithInTenKilometers.length,
                  itemBuilder: (context, index) {
                    final userId = usersWithInTenKilometers.elementAt(index);
                    final usersDatas = FirebaseFirestore.instance
                        .collection("users")
                        .doc(userId)
                        .get();
                        // I did like this, but it does not work.

                    return CustomListTile(
                      userImageUrl: "https://picsum.photos/200/300",
                      userStatus: "userStatus",
                      userName: "userName",
                    );
                  },
                );
        }
        return const CustomProgressIndicator(
          progressIndicatorColor: blackColor,
        );
      },
    );
  }
}

Consequently, I have a Set (or you can think like List), and it has user ids. Using these user ids, fetch user datas basically from the Firestore (email: ..., password: ... etc)

CodePudding user response:

  final userId = usersWithInTenKilometers.elementAt(index);
                    final users = FirebaseFirestore.instance
                        .collection("users")
                        .doc(userId)
                        .get()
                        .then((value) => value)
                        .then((value) => value.data());

                    return FutureBuilder(
                      future: users,
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          final convertUserDataToMap =
                              Map<String, dynamic>.from(snapshot.data as Map<dynamic, dynamic>);
                          final List userDataList = convertUserDataToMap.values.toList();
                          final userId = userDataList[0];
                          final userLong = userDataList[1];

....

I solved like this

CodePudding user response:

Since you get back a Future<String?>, I'd typically first consider using a FutureBuilder to render that value.

If you have multiple values that each is loaded asynchronously separately (like is the case here with your multiple get() calls), I'd start with using a separate FutureBuilder for each Future. Only if I'd run into practical problems with that, would I start considering more complex options, such as Future.wait() to wait for all of them to complete before rendering any result.

  • Related