首页 > 解决方案 > 如何在 Flutter 中基于 Future 结果构建 Stream?

问题描述

我有一个使用 Firebase-storage 和 google-signin 的 Flutter 应用程序。我想做的步骤很简单:

1- 使用谷歌登录(完成)。

2- 获取当前用户 ID(完成)。

3-在为流构建器构建流时使用用户 ID(问题)。

到目前为止我所做的是我使用 aFuture来获取当前用户 ID,然后将用户 ID 注入到Where clause

.where('userId', isEqualTo: userId)

这就是我最终的结果:

这是我应该创建流的部分:

  // Get document's snapshots and return it as stream.
  Future<Stream> getDataStreamSnapshots() async {
    // Get current user.
    final User user = await FirebaseAuth().currentUser();
    String userId = user.uid;

    Stream<QuerySnapshot> snapshots =
      db
        .collection(db)
        .where("uid", isEqualTo: userId)
        .snapshots();

    try {
      return snapshots;
    } catch(e) {
      print(e);
      return null;
    }
  }

这是我应该调用和接收流的部分,

...
children: <Widget>[
    StreamBuilder<QuerySnapshot>(
          stream: CALLING THE PREVIOUS FUNCTION,
            builder: (BuildContext context, 
                      AsyncSnapshot<QuerySnapshot> snapshot) {
                if (snapshot.hasData) {
                    ...
                }
              ...

但是这段代码不起作用,因为我无法获得 Future 应该返回的值?任何想法?

多谢

标签: firebaseflutterdartgoogle-cloud-firestorefirebase-authentication

解决方案


你永远不应该有 a Future<Stream>,那是双异步,这是不必要的。只需返回 a Stream,然后您就不必发出任何事件,直到您准备好。

目前尚不清楚try/catch正在保护什么,因为 non- 的返回Future不能抛出。如果您返回一个流,也只需在该流上发出任何错误。

您可以将代码重写为:

Stream<QuerySnapshot> getDataStreamSnapshots() async* {
  // Get current user.
  final User user = await FirebaseAuth().currentUser();
  String userId = user.uid;

  yield* db
    .collection(db)
    .where("uid", isEqualTo: userId)
    .snapshots();
}

async*函数是异步的,因此您可以使用await. 它返回 a ,然后您使用orStream在流上发出事件。yield event;yield* streamOfEvents;


推荐阅读