【问题标题】:Firestore single document snapshot stream not updatingFirestore 单文档快照流未更新
【发布时间】:2021-09-02 12:20:37
【问题描述】:

我的 Flutter 应用程序需要监听特定 Firestore 文档中的任何更改。

这个过程非常简单,可以在各种解决方案中找到:

  1. StackOverflow: flutter-firestore-how-to-listen-for-changes-to-one-document
  2. StackOverflow:can-i-listen-to-a-single-document-in-firestore-with-a-streambuilder
  3. StackOverflow:using-stream-building-with-a-specific-firestore-document
  4. StackOverflow: how-to-get-a-specific-firestore-document-with-a-streambuilder
  5. 中等: how-to-get-data-from-firestore-and-show-it-on-flutterbuilder-or-streambuilder-e05

这些都是使用StreamStreamBuilder 并监听任何变化的解决方案。

通常使用这种方法:

Stream<UserModel?> getFirestoreUser(String uid) {
  return FirebaseFirestore.instance.collection('users').doc(uid).snapshots().map((event) => event.data()).map((event) => event == null ? null : UserModel.fromJson(event));
}

地点:

  • UserModel 有一个 fromJson(Map&lt;String, dynamic&gt;) 工厂构造函数
  • 并且存在文档 ID 为 uidusers 集合。

Stream 返回一个Stream&lt;UserModel?&gt;,以后可以由Provider.of&lt;UserModel?&gt;(context)StreamBuider&lt;UserModel?&gt; 使用


问题:

TL;DR - 在更新 Firestore().getCurrentUser(uid) 流后(直接或手动使用 Firestore 模拟器并更改文档值),下面的 StreamBuilder&lt;UserModel?&gt; 不会更新。

在应用程序生命周期的所有时间点(无论是否经过身份验证),流始终返回 null(但是使用 .first 手动调用流会返回用户内容,但 .last 只是挂起)。有关详细信息,请参见下文。

链接到github project

开始:

  1. 将您自己的gooogle-services.json 文件放入android/app 文件夹中
  2. com.flutterprojects.myapp 的所有引用更改为${your google-services.json package name}
  3. 使用本地模拟器更新 Firestore 更改

更多详情:

我的问题使用了类似的方法,但 Stream 没有返回任何内容。我的 Flutter 小部件 LoggedIn()FirebaseAuth.instance.currentUser 有效(即不为空)时使用

class LoggedIn extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return StreamBuilder<UserModel?>(
      builder: (context, snapshot) {
        print("Checking UserModel from stream provider");
        if (snapshot.data == null) {
          print("UserModel is null");
          return UiLogin();
        }

        print("UserModel is NOT null");
        return UiHome();
      },
    );
  }
}

验证成功后,文本Checking UserModel from stream provider 会打印到控制台,然后是UserModel is nullUserModel is NOT null 绝不会显示。

成功验证后(即用户注册和文档更新),我有一个按钮,我手动调用流并获取第一项:

var currentUser = Firestore().getCurrentUser(FirebaseAuth.instance.currentUser!.uid);
var first = await currentUser.first;
print(first);

根据新增的用户信息返回UserModel

运行以下代码时,在.last处停止执行,没有错误,没有崩溃,没有应用退出,只是停止执行。

var currentUser = Firestore().getCurrentUser(FirebaseAuth.instance.currentUser!.uid);
var last = await currentUser.last;
print(last);

但是

添加以下内容时,所有更改都会更新并打印到控制台

Firestore().getCurrentUser(currentUid).listen((data) {
    print("Firestore Data Changed");
    print("Firestore change value: $data");
});

这意味着StreamBuilder&lt;UserModel?&gt; 无法正常工作,因为Stream&lt;UserModel&gt; 事件执行listen() 更改并确认这些更改,但StreamBuilder&lt;UserModel?&gt; 更改不会受到影响并始终返回null

我是不是做错了什么?

【问题讨论】:

  • 您是否在 StreamBuilder 中添加了 stream: 参数?

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


【解决方案1】:

试试if (snapshot.hasData) { print("UserModel is null"); return UiLogin(); }

【讨论】:

【解决方案2】:

这对我有用。也许连接状态是缺失的。

StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('users')
            .doc(widget.uid)
            .collection('contacts')
            .doc(widget.client)
            .collection('messages')
            .orderBy('timestamp', descending: true)
            .snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasError)
            return Expanded(
              child: Center(child: Text('Problem Getting Your Messages')),
            );

          switch (snapshot.connectionState) {
            case ConnectionState.none:
              return Text('waiting');
            case ConnectionState.waiting:
              return Center(child: Text('Waiting'));
            case ConnectionState.active:
              var snap;
              print('active');
              if (snapshot.data != null) {
                snap = snapshot.data;
              }
              return Expanded(
                child: ListView(
                  ...
              );

            case ConnectionState.done:
              print('done');
              return Text('Lost Connection');
          }

          return Text('NOPE');
        },
      ),

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-02
    • 2020-09-26
    • 2022-01-25
    • 2021-09-27
    • 2018-08-22
    • 1970-01-01
    • 2018-03-19
    • 2019-09-03
    相关资源
    最近更新 更多