【问题标题】:How to retrieve list using child added event of firebase in flutter?如何在flutter中使用firebase的子添加事件检索列表?
【发布时间】:2018-11-04 07:58:20
【问题描述】:

我想使用 Stream 对象的 firebase 子添加方法从我的 firebase 实时数据库中检索列表。我已经像下面这样配置了我的应用程序,但我只加载了 1 个“问题”(最新的),其余的根本没有加载。

我的数据库中确实有超过 5 个问题。如何从我的实时数据库中获取 5 个最新问题的列表?

class _QuestionPageState extends State<QuestionsPage> {
  List _questions = [];    

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
        body: new StreamBuilder(
        stream: FirebaseDatabase.instance
            .reference()
            .child('questions')
            .limitToLast(5)
            .onChildAdded,
        builder: (context, snap) {
          if (snap.hasError) return new Text('Error: ${snap.error}');
          if (snap.data == null)
            return new Center(
              child: new CircularProgressIndicator(),
            );
          print(snap.data.snapshot.key);
          print(snap.data.snapshot);
          final question = snap.data.snapshot.value;
          this._questions.add(question);
          return new ListView.builder(
            itemCount: this._questions.length,
            itemBuilder: (context, index) {
              print("question");
              print(this._questions[index]["meta"]["question"]);
              return new Text(this._questions[index]["meta"]["question"]);
            },
          );
        },
      ),
    );
  }
}

[更新] 这是数据库结构

【问题讨论】:

  • 能否将您的数据库文件附加到这个问题中?
  • @AkshayNandwana 我刚刚添加了我的数据库的图像
  • @farhana 当然,去吧
  • @farhana 我觉得自己很愚蠢,大声笑继续!

标签: firebase firebase-realtime-database dart flutter


【解决方案1】:

尽量不要使用“onChildAdded”。这只得到最近添加的孩子。您想要所有孩子,但希望将自己限制为最近的 5 个(您正在使用 limitToLast 执行此操作)。

【讨论】:

  • 在 iOS 上,childAdded 事件会为每个现有的孩子触发一次。为什么它对 Flutter 不做同样的事情?以下是 FIRDataEventTypeChildAdded 上文档中的语言:“检索项目列表或侦听项目列表的添加内容。此事件为每个现有的孩子触发一次,然后在每次将新的孩子添加到指定的路径时再次触发。侦听器会收到一个包含新孩子数据的快照。”来源:firebase.google.com/docs/database/ios/lists-of-data
  • 那是愚蠢的 - 得到所有孩子?!如果有 100,000,000,000,000 怎么办? @EricDuffett 的响应对我有用,尽管我希望能够更早地取消侦听器,因为 Firebase 限制了并发连接的数量。 JavaScript 会让你引用返回的 updates 并在你计算出 5 个结果时取消它,但 Dart 似乎不喜欢这样。
【解决方案2】:

我也遇到了这个问题,发现不使用 StreamBuilder 小部件更容易。使用 StreamBuilder 时,我必须使用 .onValue 而不是 .onChildAdded 才能返回所有子项,但 .onValue 以不可预测的顺序返回子项,因为它以地图的形式返回。

相反,我认为最好创建一个 StreamSubscription 并在 initState() 中调用它,如下所示。新的孩子被添加到数组中,并且该数组用于构建 ListView。我在索引 0 处插入新的孩子,以便最新的帖子位于表格的顶部。

class NotificationsFeedPage extends StatefulWidget {
  @override
  _NotificationsFeedPageState createState() => _NotificationsFeedPageState();
}

class _NotificationsFeedPageState extends State<NotificationsFeedPage> {

  List <Notification> notificationList = [];

  StreamSubscription <Event> updates;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    updates = FirebaseDatabase.instance.reference().child('notifications').child(currentUser.uid).limitToLast(50).onChildAdded.listen((data) {
      notificationList.insert(0, Notification.fromFireBase(data.snapshot));
      setState(() {

      });
    } );
  }

  @override
  void dispose() {
    // TODO: implement dispose

    updates.cancel();
    super.dispose();
  }

其中通知是一个自定义类,如下所示:

class Notification {
  String name;
  bool isComment;
  String user;
  String comment;

  Notification.fromFireBase(DataSnapshot snapshot) {
    this.name = snapshot.value["name"] ?? 'Unknown user';
    this.isComment = snapshot.value["isComment"] ?? false;
    this.user = snapshot.value["user"] ?? '';
    this.comment = snapshot.value["comment"] ?? '';
  }
}

这会继续监听直到视图被释放。调用 updates.cancel() 时停止监听。

【讨论】:

    猜你喜欢
    • 2020-12-11
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 2021-02-03
    • 2020-01-05
    • 1970-01-01
    相关资源
    最近更新 更多