skip to Main Content

In a chat app I’m trying to query Firestore and return the other user’s name as a String from a ‘Contacts’ collection. I’m still trying to wrap my head around async and Futures in dart, so when I return this, it prints ‘Instance of Future’ instead of the string that findName should query for.

return ListView(
                    children: List.generate(_conversations.length, (i) {
                      

                      DocumentReference? _conversationRef =
                          _conversations[i].reference;
                      Map _conversation = _conversations[i].data() ?? {};



                      String otherUser = _conversation["members"][0] != uid
                          ? _conversation["members"][0]
                          : _conversation["members"][1];



                      Future<String> findName(otherUser) async {
                        var recipName = await FirebaseFirestore.instance
                            .collection("contacts")
                            .where("phone_number", isEqualTo: otherUser)
                            .get().then(

                              (querySnapshot) {
                                 for (var docSnapshot in querySnapshot.docs) {

                                   return docSnapshot.data()['full_name'].toString();
                                 }
                              });


                            if (recipName != null) {
                              return recipName;
                            } else {
                              return otherUser;
                            }
                      }

                      
                      contactName() async {
                        var name = await findName(otherUser);
                        return name.toString();
                      }


                      return ConversationTile(
                          conversationReference: _conversationRef,
                          otherUserId: contactName() ?? "user number");
                    }),

2

Answers


  1. If you are building UI off of a future, you want to use FutureBuilder, it makes controlling the state of the result of the future and rendering the ui once the future is complete. Below is a simple example of FutureBuilder, i can provide more details if needed.

    FutureBuilder(
     future: getMessages(),
     builder:(context, snapshot) {
      if (snapshot.hasData) { // Future Complete 
       return ListView.builder(itemBuilder:(context, index) {
        //build listview 
       },);
      }
     },
     return Center(child: CircularProgressIndicator()); // Future Not Complete / No Data
    ),
    
    Login or Signup to reply.
  2. In Dart you can return a String from a Future by using the async and await keywords. Follow this link https://dart.dev/codelabs/async-await

    In your case updated code will be-

    return ListView(
      children: List.generate(_conversations.length, (i) {
        DocumentReference? _conversationRef = _conversations[i].reference;
        Map _conversation = _conversations[i].data() ?? {};
    
        String otherUser = _conversation["members"][0] != uid
            ? _conversation["members"][0]
            : _conversation["members"][1];
    
        Future<String> findName(String otherUser) async {
          var querySnapshot = await FirebaseFirestore.instance
              .collection("contacts")
              .where("phone_number", isEqualTo: otherUser)
              .get();
    
          for (var docSnapshot in querySnapshot.docs) {
            return docSnapshot.data()['full_name'].toString();
          }
    
          return otherUser;
        }
    
        return FutureBuilder<String>(
          future: findName(otherUser),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ConversationTile(
                conversationReference: _conversationRef,
                otherUserId: snapshot.data!,
              );
            } else if (snapshot.hasError) {
              return Text("Error: ${snapshot.error}");
            } else {
              return CircularProgressIndicator();
            }
          },
        );
      }),
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search