提问人:jamesglv 提问时间:5/28/2023 更新时间:5/28/2023 访问量:45
如何在 Dart 中从 Future<String> 返回聊天应用程序的字符串?
How to return a String from a Future<String> in Dart for a chat app?
问:
在聊天应用程序中,我尝试查询 Firestore 并从“Contacts”集合中以字符串形式返回其他用户的名称。我仍在尝试在 dart 中围绕 async 和 Futures 进行思考,因此当我返回此内容时,它会打印“Instance of Future”而不是 findName 应查询的字符串。
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");
}),
答:
0赞
CStark
5/28/2023
#1
如果要基于未来构建 UI,则需要使用 FutureBuilder,它可以控制未来结果的状态,并在未来完成后呈现 UI。下面是 FutureBuilder 的简单示例,如果需要,我可以提供更多详细信息。
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
),
0赞
Vinay
5/28/2023
#2
在 Dart 中,你可以使用 async 和 await 关键字从 Future 返回一个字符串。请点击此链接 https://dart.dev/codelabs/async-await
在您的情况下,更新的代码将是-
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();
}
},
);
}),
);
评论
0赞
Imtiaz Ayon
5/28/2023
你不应该在将来的构建器中运行异步函数,因为这样你每次构建小部件时都会运行这个函数。您应该在 initState 或其他地方调用它(不使用 await),并在将来的构建器中使用该变量。api.flutter.dev/flutter/widgets/FutureBuilder-class.html(管理未来)
评论
T
Future<T>
await
await
Futuer.then