代码之家  ›  专栏  ›  技术社区  ›  dshukertjr

如何使用flutter中的firebase子添加事件来检索列表?

  •  1
  • dshukertjr  · 技术社区  · 6 年前

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

    我的数据库里有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"]);
                },
              );
            },
          ),
        );
      }
    }
    

    [更新] 这是数据库结构

    This is the structure of my database

    2 回复  |  直到 6 年前
        1
  •  0
  •   Wm Leler    6 年前

    尽量不要使用“onchildaded”。只会得到最近添加的子项。你想要所有的孩子,但是想把自己限制在最近的5个(你用limittolast做的)。

        2
  •  -1
  •   Eric Duffett    6 年前

    我也遇到了这个问题,发现不使用StreamBuilder小部件更容易。使用streambuilder时,我必须使用.onvalue而不是.onchildeded来返回所有子级,但是.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()时停止侦听。