如何基于Flutter中的Future结果构建流?

时间:2019-06-25 17:52:58

标签: firebase flutter dart google-cloud-firestore firebase-authentication

我有一个Flutter应用程序,该应用程序使用Firebase存储和google登录。 我要尝试的步骤是如此简单:

1-使用Google登录(完成)。

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

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

到目前为止,我所做的是我正在使用Future来获取当前用户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应该返回的值?有什么主意吗?

非常感谢

1 个答案:

答案 0 :(得分:2)

您永远不应该有一个Future<Stream>,它是双重异步的,这是不必要的。只需返回一个Stream,然后您就不必准备发出任何事件。

目前尚不清楚try / catch所保护的内容,因为返回非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。它返回一个Stream,并且您可以使用yield event;yield* streamOfEvents;在流中发射事件。