0

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)

5
  • The Firebase Realtime Database and Cloud Firestore are two separate databases. Please only mark your question with the relevant tag, not with both. --- Since you get back a Future<String?> did you consider wrapping it in a FutureBuilder? Commented Jun 2, 2022 at 12:06
  • Above, I used streambuilder. After that I use listviewbuilder to use index, then I do not want to wrap with futurebuilder. If I do this, every item had future builder, and it is not good. Any idea? Commented Jun 2, 2022 at 12:13
  • I recommend either letting go of the notion that having multiple FutureBuilders is bad. If you have a Future you will need to handle the asynchronous nature of that future when displaying its value in the UI, and the FutureBuilder class was made for that specific purpose. Commented Jun 2, 2022 at 12:48
  • So Let see If I understand clearly. You suggest that I do not use 2 future builder right ? If yes, then is there any other option? Commented Jun 2, 2022 at 12:57
  • If you have a value that is asynchronously loaded, it shows up as a Future in your code. When you have a Future, the idiomatic approach is to use a FutureBuilder to display that value. If each value is asynchronously separately (like is the case here with your multiple get() calls), I don't see a problem (in principle) with using a separate FutureBuilder for each Future. Commented Jun 2, 2022 at 14:31

2 Answers 2

0
  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

Sign up to request clarification or add additional context in comments.

Comments

0

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.

2 Comments

where can I use future.wait() ? Instead of top of the future builder or where?
As I said, I'd only use that option if you run into problems. Did you already try using a FutureBuilder for each Future that you get?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.