Getting data from cloud firestore onto a listview in flutter

7,252

In Your Code - Edit - widget.event['id'] to - widget.event.data['id'] & So On same with Other Places where you have Snapshot variable used...

As Per Documentation - DocumentSnapshot

A DocumentSnapshot contains data read from a document in your Cloud Firestore database. The data can be extracted with .data()

widget.event is - DocumentSnapshot & to read the data you need to use .data Method.

Also the Error you are Getting is of Code :

child: StreamBuilder(
          stream: Firestore.instance.collection('events').snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) return Text('Loading data... Please wait');
            return snapshot.data.documents.map(
              (document) => Column(
                              ......

Here Builder is Expecting a Widget as a return value not 'MappedListIterable' -

snapshot.data.documents.map(
                  (document) // is Wrong return value for StreamBuilder.

You Need Modify Your Code to return a widget here.

Share:
7,252
theSimm
Author by

theSimm

Updated on December 08, 2022

Comments

  • theSimm
    theSimm over 1 year

    I am trying to pull data from a firebase cloud firestore collection (events) onto a list view, I’m not sure if I am implementing this correctly, when I run the app I get the error 'MappedListIterable' is not a subtype of type 'Widget'. This is my first time working with firebase cloud firestore and I could really use some help in better understanding this error.

    This is where the list view is being initialized:

        import 'package:flutter/material.dart';
    import 'package:rallie_app/utils/event_summary.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    
    
    class HomeList extends StatelessWidget {
    
     Firestore db = Firestore.instance; 
    
    
    
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child: StreamBuilder<QuerySnapshot>(
              stream: Firestore.instance.collection('events').snapshots(),
              builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
               // count of events
                final int eventCount = snapshot.data.documents.length;
                if (snapshot.hasError)
                  return new Text('Error: ${snapshot.error}');
                switch (snapshot.connectionState){
                  case ConnectionState.waiting:
                    return Center(child: CircularProgressIndicator());
                  default:
                    return new ListView.builder(
                        itemCount: eventCount ,
                      itemBuilder: (context, index) {
                        final DocumentSnapshot document = snapshot.data.documents[index];
                      return  new EventSummary(document);
                      }
                    );
                }
              })
    
    
    
        );
      }
    }
    

    These are the list view items I wish to build :

         import 'package:flutter/material.dart';
    import 'package:rallie_app/model/events.dart';
    import 'package:rallie_app/ui/detail/detail_page.dart';
    import 'package:rallie_app/services/firestore_service.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'dart:async';
    
    class EventSummary extends StatefulWidget {
      //TODO: Event summary constructor with event model class initialized in it
    
      final DocumentSnapshot event;
    
      EventSummary(this.event);
    
      @override
      _EventSummaryState createState() => _EventSummaryState();
    }
    
    class _EventSummaryState extends State<EventSummary> {
      @override
      Widget build(BuildContext context) {
        final userThumbnail = new Container(
          margin: EdgeInsets.symmetric(vertical: 16.0),
          alignment: FractionalOffset.centerLeft,
          child: Hero(
            tag: "user-image-${widget.event.data['id']}",
            child: CircleAvatar(
              backgroundImage: AssetImage(widget.event['event_poster_image']),
              // backgroundColor: Colors.white,
              maxRadius: 40.0,
            ),
          ),
        );
    
        final eventCardContent = Container(
          margin: new EdgeInsets.only(left: 46.0),
          decoration: new BoxDecoration(
            shape: BoxShape.rectangle,
            color: new Color(0xFFFFFFFF),
            borderRadius: new BorderRadius.circular(8.0),
            image: DecorationImage(
              image: AssetImage(widget.event.data['event_image']),
              fit: BoxFit.fill,
            ),
          ),
        );
    
        Widget _eventValue(){
          return Column(
            children: <Widget>[
              Container(
                height: 150.0,
                margin: const EdgeInsets.symmetric(
                  vertical: 16.0,
                  horizontal: 24.0,
                ),
                child: new Stack(
                  children: <Widget>[
                    eventCardContent,
                    userThumbnail,
                  ],
                ),
              ),
              Container(
                margin: const EdgeInsets.only(left: 70.0, bottom: 20.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      widget.event.data['event_name'],
                      textAlign: TextAlign.start,
                    ),
                    Row(
                      //crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          widget.event.data['event_date'],
                          textAlign: TextAlign.start,
                        ),
                        SizedBox(
                          width: 110,
                        ),
                        IconButton(
                          icon: Icon(Icons.share),
                          splashColor: Colors.orange,
                          tooltip: 'Share button',
                          onPressed: () =>
                              debugPrint('Share btn tapped'),
                        )
                      ],
                    ),
                    Text(
                      widget.event.data['event_attending'],
                      textAlign: TextAlign.start,
                    ),
                  ],
                ),
              )
            ],
          );
        }
    
        return new GestureDetector(
          onTap: () => Navigator.of(context).push(
                new PageRouteBuilder(
                  pageBuilder: (_, __, ___) => new DetailPage(widget.event.data['id']),
                  transitionsBuilder:
                      (context, animation, secondaryAnimation, child) =>
                          new FadeTransition(opacity: animation, child: child),
                ),
              ),
          child: StreamBuilder(
              stream: Firestore.instance.collection('events').snapshots(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) return Text('Loading data... Please wait');
                return snapshot.data.documents.map(
                  (document) => _eventValue()
                );
              }),
        );
      }
    }
    
  • theSimm
    theSimm over 5 years
    So I created a method of type widget that returned the column and called the method as a return value for the stream builder and i'm still gettitng ' MappedListIterable<DocumentSnapshot, dynamic>' is not a subtype of type 'Widget' error this has been updated in my code above
  • anmol.majhail
    anmol.majhail over 5 years
    You are Still returning - snapshot.data.documents.map - this will never Work. This Code Return MappedListIterable<DocumentSnapshot, dynamic> not any Widget.
  • theSimm
    theSimm over 5 years
    Thanks for your help!