【问题标题】:Firebase Realtime Database and Flutter - Snapshot has no dataFirebase 实时数据库和 Flutter - 快照没有数据
【发布时间】:2021-01-21 13:59:36
【问题描述】:

我尝试在 Flutter 中实现 Firebase 实时数据库,我想实时显示更新的值。我尝试使用StreamBuilder 来实现这一目标。

StreamBuilder 代码

StreamBuilder(
  stream: GuestbooksDatabase().getAllGuestbooksSync().asStream(),
  builder: (context, snapshot) {
    if (!snapshot.hasData || !snapshot.data.length) {
      return CircularProgressIndicator();
    } else {
      return ListView.builder(
          shrinkWrap: true,
          itemCount: snapshot.data.length,
          itemBuilder: (context, index) {
            return Text(snapshot.data[index].title);
          });
    }
  }),

流函数

Future<List<Guestbook>> getAllGuestbooksSync() async {
    List<Guestbook> guestbooks = [];
    databaseRef.onValue.listen((event) async {
      var dataSnapshot = event.snapshot;

      if (dataSnapshot.value != null) {
        dataSnapshot.value.forEach((key, value) async {
          Guestbook guestbook = await Guestbook.fromJson(value);
          guestbook.setId(key);
          guestbooks.add(guestbook);
        });

        await Future.delayed(Duration.zero);
        print(guestbooks); // Result: All Instances of Guestbook
        return guestbooks;
      }
    });
  }

我只看到CircularProgressIndicator() 这意味着快照没有数据。 有什么问题?

【问题讨论】:

  • 是什么意思!snapshot.data.length
  • 快照数据长度时触发
  • 您是否已经检查了snapshot.hasData || !snapshot.data.length 中的两个条件中的哪一个是正确的?因为后者意味着读取完成,但是导致没有数据,而前者意味着读取从未完成。另外:您是否检查了应用程序的输出是否有错误/警告?
  • 如果我在 StreamBuilder 中print(snapshot.data),结果是null。所以没有数据,!snapshot.hasData 条件为真。
  • PS:没有错误,没有警告。从getAllGuestbooksSync() 我得到正确的输出,但StreamBuilder 不知道它...:/

标签: flutter dart firebase-realtime-database


【解决方案1】:

您可以为此使用StreamController

创建一个新的控制器 -

final StreamController streamController = StreamController<List>.broadcast();

Future&lt;List&gt; 转换为void 类型以用于您的getAllGuestbooksSync() 函数并且不返回任何内容。

它可以并且将会在initState()中被调用-

void getAllGuestbooksSync() {
    List<Guestbook> guestbooks = [];
    databaseRef.onValue.listen((event) async {
      var dataSnapshot = event.snapshot;

      if (dataSnapshot.value != null) {
        dataSnapshot.value.forEach((key, value) async {
          Guestbook guestbook = await Guestbook.fromJson(value);
          guestbook.setId(key);
          guestbooks.add(guestbook);
        });

        print(guestbooks); // Result: All Instances of Guestbook

        streamController.add(guestbooks); // Adding list to the stream
      }
    });
}

在您的StreamBuilder 中使用-

stream: streamController.stream,

【讨论】:

  • 如果我在与 StreamBuilder 相同的文件中使用该函数,这有效,对吗?我在我用作数据库服务的单独文件中使用getAllGuestbooksSync()。这只是一个没有 Stateless 小部件或 StateFul Widget 的类。所以没有initState。这也有用吗?
  • 您可以在单独的文件中使用不同的控制器,然后您可以将控制器对象从一个类传递给另一个类(文件到另一个)。它应该像那样工作。
  • 不工作。日志永久显示flutter: AsyncSnapshot&lt;dynamic&gt;(ConnectionState.waiting, null, null)
  • 如果您可以链接示例代码,那么查看问题所在和位置将很有帮助
猜你喜欢
  • 2022-01-21
  • 2021-06-07
  • 2020-04-28
  • 2021-11-17
  • 2021-07-01
  • 2021-03-26
  • 2022-08-05
  • 1970-01-01
  • 2023-04-10
相关资源
最近更新 更多