flutterdartcloudevents

Flutter - how to read list from Firebase realtime database using model


[ Sorry for my bad English ]

In this project I'm viewing events lists in some pages from JSON API and in CloudEvents page I'm viewing another list from Firebase Database, using Event model ...

Now when I run CloudEvents page I get null for itemsEvent[i].startDate

with this Error: A non-null String must be provided to a Text widget.

Open: Error Snapshot

Open: Firebase Database Snapshot

I used this Method for my model

This is my Event model

    class Event {
          String key;
          String sectionID;
          String sectionTitle;
          String title;
          String startDate;
          String endDate;
          String startDateAr;
          String endDateAr;
          String city;
          String detail;
          String location;
          String more;
          String link;

          // for generalevent.json
          String eventDate;
          String eventDateAr;

          Event(
              {this.sectionID,
              this.sectionTitle,
              this.title,
              this.startDate,
              this.endDate,
              this.startDateAr,
              this.endDateAr,
              this.city,
              this.detail,
              this.location,
              this.more,
              this.link,
              this.eventDate,
              this.eventDateAr});

          factory Event.fromJson(Map<String, dynamic> json) {
            return Event(
              sectionID: json['section-id'],
              sectionTitle: json['section-title'],
              title: json['title'],
              startDate: json['start-event-date'],
              endDate: json['end-event-date'],
              startDateAr: json['start-event-date-ar'],
              endDateAr: json['end-event-date-ar'],
              city: json['city'],
              detail: json['detail'],
              location: json['location'],
              more: json['more'],
              link: json['link'],

              // for generalevent.json
              eventDate: json['event-date'],
              eventDateAr: json['event-date-ar'],
            );
          }

          Event.fromSnapshot(DataSnapshot snapshot)
              : key = snapshot.key,
                title = snapshot.value['title'],
                startDate = snapshot.value['startDate'];

          toJson() {
            return {
              "title": title,
              "startDate": startDate,
            };
          }

        }

And this is my CloudEvents page

    import 'package:events/UI/styleguide.dart';
    import 'package:events/models/event.dart' as e;
    import 'package:events/pages/account.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:firebase_database/firebase_database.dart';
    import 'package:firebase_database/ui/firebase_animated_list.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/rendering.dart';
    import 'package:intl/intl.dart' as intl;

    final FirebaseAuth mAuth = FirebaseAuth.instance;
    final db = FirebaseDatabase.instance.reference();
    FirebaseUser mCurrentUser;

    List<e.Event> itemsEvent = List();
    e.Event itemEvent;
    DatabaseReference dbEvent;



    class CloudEvents extends StatefulWidget {
      final GlobalKey<ScaffoldState> scaffoldKey;

      const CloudEvents({Key key, @required this.scaffoldKey}) : super(key: key);

      @override
      _CloudEventsState createState() => _CloudEventsState();
    }

    class _CloudEventsState extends State<CloudEvents> {
      ScrollController _hideButtonController;
      var _isVisible;

      @override
      initState() {
        super.initState();

        ...
        
        itemEvent = e.Event();
        final FirebaseDatabase database = FirebaseDatabase.instance;
        dbEvent = database.reference().child('events');
        dbEvent.onChildAdded.listen(_onEntryAddedEvent);
        dbEvent.onChildChanged.listen(_onEntryChangedEvent);

        ...
      }

      _onEntryAddedEvent(Event event) {
        setState(() {
          itemsEvent.add(e.Event.fromSnapshot(event.snapshot));
        });
      }

      _onEntryChangedEvent(Event event) {
        var old = itemsEvent.singleWhere((entry) {
          return entry.key == event.snapshot.key;
        });
        setState(() {
          itemsEvent[e.Event.indexOf(old)] = e.Event.fromSnapshot(event.snapshot);
        });
      }

      @override
      Widget build(BuildContext context) {
        return showEvents();
      }

      Widget showEvents(BuildContext context) {

        return Container(
          height: MediaQuery.of(context).size.height,
          child: Stack(
            children: <Widget>[
              FirebaseAnimatedList(
                  query: dbEvent.child(mCurrentUser.uid),
                  itemBuilder: (_, DataSnapshot snapshot,
                      Animation<double> animation, int i) {
                    return new ListTile(
                      title: new Text(snapshot.value['title']),  //snapshot works well 
                      subtitle: new Text(itemsEvent[i].startDate), // this returns null
                    );
                  }),

              ...

            ],
          ),
        );
      }

      ...

    }

Solution

  • I just realized the problem here, according to u/Cholojuanito's comment on reddit

    I did his number 1 possible solution, and then I edited:

    Text(itemsEvent[i].startDate) to Text(e.Event.fromSnapshot(snapshot).startDate)

    and it worked so well, thank you for everyone who commented on reddit.