firebase - 如何在 map() 中使用异步代码(Flutter、Firestore)

标签 firebase flutter dart google-cloud-firestore

我正在使用 Flutter 和 Firestore 插件开发群聊应用。从数据库中获取数据并将快照转换为消息列表完全可以。但现在我想将数据库中的 uid 转换为用户名(uid 及其用户名保存在数据库中)。这是我的代码:

final CollectionReference messagesCollection =
    Firestore.instance.collection('messages');

final CollectionReference usersCollection =
    Firestore.instance.collection('users');

Future<String> getUsernameByUID(String _uid) async {
  String username =
      await usersCollection.document(uid).get().then((querySnapshot) {
    return (querySnapshot.data["username"]);
  });
  return username;
}

List<Message> _messagesFromSnapshot(QuerySnapshot snapshot){
  return snapshot.documents.map((doc) {

    String username = await getUsernameByUID(doc.data["uid"]);

    return Message(
      text: doc.data["text"] ?? "",
      username: username ?? "",
      time: doc.data["time"] ?? "",
    );
  }).toList();
}


Stream<List<Message>> get messages {
  return messagesCollection
      .orderBy("time")
      .snapshots()
      .map(_messagesFromSnapshot);
}

问题出在这一行,因为我无法在 map() 内部运行此异步代码。

String username = await getUsernameByUID(doc.data["uid"]);

有解决办法吗?提前致谢。

最佳答案

async函数必须返回 Future , 所以加入 async您的回调关键字意味着您的 List.map()现在调用必须返回 ListFuture

您可以转换 List<Future<Message>>List<Message>通过使用 Future.wait :

Future<List<Message>> _messagesFromSnapshot(QuerySnapshot snapshot) async {
  var futures = snapshot.documents.map((doc) async {
    String username = await getUsernameByUID(doc.data["uid"]);

    return Message(
      text: doc.data["text"] ?? "",
      username: username ?? "",
      time: doc.data["time"] ?? "",
    );
  });

  return await Future.wait(futures);
}

当然,Future.wait返回 Future并且必须是 await ed,所以现在_messagesFromSnapshot必须是 async以及。异步是会传染的,然后会影响 _messagesFromSnapshot 的所有调用者.

messages getter 返回一个 Stream并且已经是异步的,我相信你可以改用 Stream.asyncMap :

Stream<List<Message>> get messages {
  return messagesCollection
      .orderBy("time")
      .snapshots()
      .asyncMap(_messagesFromSnapshot);
}

关于firebase - 如何在 map() 中使用异步代码(Flutter、Firestore),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58978730/

相关文章:

node.js - 使用 Nodejs 实时抓取聊天记录

android - Flutter android_alarm_manager 插件不定期运行

android - 停止视频播放器日志 flutter

dart - 如何向 Flutter 应用程序添加水平卡片轮播 View

javascript - Google Cloud Function 未定义参数检测为 null

firebase - 如何以经过身份验证的用户身份在函数 :shell 中测试 onCall 函数

node.js - Cloud Functions for Firebase - 未配置结算帐号

flutter ElevatedButton 问题

android - 如何使用singleWhere .. flutter访问列表内的项目

flutter - 从 Stream (Flutter) 控制 Carousel Slider