NoSuchMethodError. The getter 'weekday' was called on null. Table_Calendar Flutter - firebase

I'm stuck with the table calendar.
In Android Studio I get following error:
The following NoSuchMethodError was thrown building StreamBuilder<List<AppEvent>>(dirty, state: _StreamBuilderBaseState<List<AppEvent>, AsyncSnapshot<List<AppEvent>>>#c5581):
The getter 'weekday' was called on null.
Receiver: null
Tried calling: weekday
This is my code: If necessarily I can post more code such the classes.
The other code works perfekt. even in the red issuescreen in the app I can trigger the floated button and add an event. But I cant see the calendar anymore cause the red issuescreen.
import 'package:app_tennis_sv_schwaig/kalender/add_event.dart';
import 'package:app_tennis_sv_schwaig/kalender/event_details.dart';
import 'package:app_tennis_sv_schwaig/kalender/event_firestore_service.dart';
import 'package:app_tennis_sv_schwaig/kalender/app_event.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:table_calendar/table_calendar.dart';
class TennisKalender extends StatefulWidget {
#override
_TennisKalenderState createState() => _TennisKalenderState();
}
class _TennisKalenderState extends State<TennisKalender> {
CalendarController _calendarController = CalendarController();
Map<DateTime, List<AppEvent>> _groupedEvents;
_groupEvents(List<AppEvent> events) {
_groupedEvents = {};
events.forEach((event) {
DateTime date =
DateTime.utc(event.date.year, event.date.month, event.date.day, 12);
if (_groupedEvents[date] == null) _groupedEvents[date] = [];
_groupedEvents[date].add(event);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.orange,
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("Tenniskalender"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.person),
onPressed: (null),
)
],
),
body: SingleChildScrollView(
child: StreamBuilder(
stream: eventDBS.streamList(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
final events = snapshot.data;
_groupEvents(events);
DateTime selectedDate = _calendarController.selectedDay;
final _selectedEvents = _groupedEvents[selectedDate] ?? [];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Card(
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(8.0),
child: TableCalendar(
calendarController: _calendarController,
events: _groupedEvents,
onDaySelected: (date, events, holidays) {
setState(() {});
},
startingDayOfWeek: StartingDayOfWeek.monday,
headerStyle: HeaderStyle(
decoration: BoxDecoration(
color: Colors.red,
),
headerMargin: const EdgeInsets.only(bottom: 8.0),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 12.0, top: 8.0),
child: Text(
DateFormat('EEEE, dd MMMM, yyyy').format(selectedDate),
style: Theme.of(context).textTheme.headline6,
),
),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: _selectedEvents.length,
itemBuilder: (BuildContext context, int index) {
AppEvent event = _selectedEvents[index];
return ListTile(
title: Text(event.title),
subtitle: Text(DateFormat("EEEE, dd MMMM, yyyy")
.format(event.date)),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => EventDetails(
event: event,
)),
);
},
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => AddEventPage(
event: event,
)));
},
));
},
),
],
);
}
return CircularProgressIndicator();
},
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.grey[900],
),
backgroundColor: Colors.yellow,
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => AddEventPage(
selectedDate: _calendarController.selectedDay,
),
),
);
}),
);
}
}
I dont get it where the weekday is written null.
Can you please help? Thanks a lot!

I solved it. In fact others have a similar issue here's my solution.
The DateFormat in the ListTile from the ListView.builder was the Problem. Don't know why but I deleted it, cause don't needed the view in the app anyway.
Errorcommand:
subtitle: Text(DateFormat("EEEE, dd MMMM, yyyy").format(event.date)),

Related

Flutter/Firebase - Right Track?

At 54 I'm self-learning Flutter and have come a long way. I am stuck (again) with a speed-bump concerning my implementation of Firebase. Although I am getting the very basic of displaying a line of data for each record the problem is getting to the details of each record. I believe the issue is that I am not referencing the record ID.
When looking at endless examples I also believe my code to display a ListView of records is bloated making it more difficult to grab a record and display all fields (edit screen).
I want to click the "Walsh-Test" links to view all fields and update. I can create a new edit/update screen my initial problem is opening the screen to the selected record.
Any advice would be greatly appreciated.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/rendering.dart';
class MeterReadHomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Color(0xff4367b1),
automaticallyImplyLeading: false,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
title: Text(
"WelakaOne",
style: TextStyle(
color: Colors.white,
),
),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('meter_reads')
.orderBy('accountname')
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return Padding(
padding: const EdgeInsets.fromLTRB(6, 20, 0, 0),
child: Container(
child: GestureDetector(
onTap: () {},
child: ListView(
children: snapshot.data.docs.map(
(document) {
return Row(
children: [
Container(
width: 50,
child: Icon(
Icons.access_alarm,
size: 36,
color: Color(0xff4367b1),
),
),
Container(
child: Text(
document['accountname'],
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xff4367b1),
),
),
),
SizedBox(height: 44),
],
);
},
).toList(),
),
),
),
);
},
),
);
}
}
[![Flutter/Firebase/Open to Selected Record][1]][1]
I understand that you want to go to another page (Edit Screen) onTapping the alarm tile.
So, my suggestion is to use A ListTile widget instead of the row widget you are using.
You can read about ListTile's onTap property, here
Regarding your routing to a new screen/page, you'll have to make use of MaterialPageRoute to create a new route and using Navigator's push method you can push it onto your Material App.
Attaching an example code that uses Navigator to go to different pages, you need the BuildContext of your app. Here is an example of how you can get it:
import 'package:flutter/material.dart';
import 'package:rate_your_professor/screens/firstScreen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Some App',
home: SomeApp(),
);
}
}
class SomeApp extends StatelessWidget {
Widget getListView(BuildContext context) {
var listView = ListView(
children: <Widget>[
Text(
"XXXXXXXXXXXXXXX",
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
),
ListTile(
leading: Icon(Icons.location_city),
title: Text("XXXXX ", textDirection: TextDirection.rtl),
subtitle: Text(
"XXXXXXXXXX",
textDirection: TextDirection.rtl,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => YourNewPage(),
),
);
},
),
],
);
return listView;
}
#override
Widget build(BuildContext context) {
return Scaffold(body: getListView(context));
}
}

non-null String must be provided to a Text widget. In Flutter showing the data != null'

I was creating a todo app in flutter with backend support of firebase everything was going ok but when I included the DocumentSnapshot that gives me error. I couldn't find a way to fix this issue.
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 285 pos 10: 'data != null'
after the line included
documentSnapshot["todoTitle"]
How can I figure this out?
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class todoUi extends StatefulWidget {
#override
_todoUiState createState() => _todoUiState();
}
class _todoUiState extends State<todoUi> {
List todos = List();
String input = "";
createTodos() {
DocumentReference documentReference =
Firestore.instance.collection("MyTodos").document(input);
//Maping
Map<String, String> todos = {"todosTitle": input};
documentReference.setData(todos).whenComplete(() {
print("$input created");
});
}
deleteTodos() {}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sharjeel's TODO LIST"),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.purple,
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
title: Text("Add Your Task"),
content: TextField(
onChanged: (String value) {
input = value;
},
),
actions: <Widget>[
FlatButton(
onPressed: () {
createTodos();
Navigator.of(context).pop();
},
child: Text("Add"))
],
);
});
},
child: Icon(
Icons.add,
color: Colors.white,
),
),
body: StreamBuilder(
stream: Firestore.instance.collection("MyTodos").snapshots(),
builder: (context, snapshots) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshots.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshots.data.documents[index];
return Dismissible(
key: Key(index.toString()),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
margin: EdgeInsets.all(8),
child: ListTile(
title: Text(
documentSnapshot["todoTitle"]
),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: () {
setState(() {
todos.removeAt(index);
});
})),
),
);
});
}),
);
}
}
I guess that's because when your widget mounts the first time it is yet to get data from the Stream.
Maybe try :
Text(documentSnapshot["todoTitle"] ?? "")

How to make a streambuilder return data in other screens

I am new in Flutter, I have a question about an implementation I want to add my app, I would appreciate your answers, let me know if you need me to give you more information.
I hope, this is clear.
Here is the implementation I want to add my app...
I have a streambuilder in my home page(see below code implementing a container that has a streambuilder as a child) that gets data from firebase(the data is users information) and returns a Listview.builder that builds a list of containers with data like name and email(for each user) in my home screen...now, how can I replace the listView.builder and instead of having those users in a listview.builder, I actually want those users information to be saved one by one into different screens(like creating a user profile for each user).
This is the streambuilder:
Container(
///this is a regular streambuilder as a child of a container
child: StreamBuilder(
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
);
} else {
///THIS IS THE LISTVIEW.BUILDER
return ListView.builder(
padding: EdgeInsets.all(10.0),
///These are some methods that build the containers list with the users information
itemBuilder: (context, index) =>
buildItem(context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
},
),
),
COMPLETE CODE FOR MY HOMEPAGE
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:jobly10/chat_implementation/settings.dart';
import 'chat.dart';
import 'const.dart';
import '../main.dart';
class HomeListViewUsers extends StatefulWidget {
final String currentUserId;
HomeListViewUsers({Key key, this.currentUserId}) : super(key: key);
#override
State createState() => HomeListViewUsersState(currentUserId: currentUserId);
}
class HomeListViewUsersState extends State<HomeListViewUsers> {
HomeListViewUsersState({Key key, #required this.currentUserId});
final String currentUserId;
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final GoogleSignIn googleSignIn = GoogleSignIn();
bool isLoading = false;
List<Choice> choices = const <Choice>[
const Choice(title: 'Settings', icon: Icons.settings),
const Choice(title: 'Log out', icon: Icons.exit_to_app),
];
#override
void initState() {
super.initState();
registerNotification();
configLocalNotification();
}
void registerNotification() {
firebaseMessaging.requestNotificationPermissions();
firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
Platform.isAndroid
? showNotification(message['notification'])
: showNotification(message['aps']['alert']);
return;
}, onResume: (Map<String, dynamic> message) {
print('onResume: $message');
return;
}, onLaunch: (Map<String, dynamic> message) {
print('onLaunch: $message');
return;
});
firebaseMessaging.getToken().then((token) {
print('token: $token');
Firestore.instance
.collection('users')
.document(currentUserId)
.updateData({'pushToken': token});
}).catchError((err) {
Fluttertoast.showToast(msg: err.message.toString());
});
}
void configLocalNotification() {
var initializationSettingsAndroid =
new AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = new IOSInitializationSettings();
var initializationSettings = new InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
void onItemMenuPress(Choice choice) {
if (choice.title == 'Log out') {
handleSignOut();
} else {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Settings()));
}
}
void showNotification(message) async {
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
Platform.isAndroid
? 'com.dfa.flutterchatdemo'
: 'com.duytq.flutterchatdemo',
'Flutter chat demo',
'your channel description',
playSound: true,
enableVibration: true,
importance: Importance.Max,
priority: Priority.High,
);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
print(message);
await flutterLocalNotificationsPlugin.show(0, message['title'].toString(),
message['body'].toString(), platformChannelSpecifics,
payload: json.encode(message));
}
Future<Null> handleSignOut() async {
this.setState(() {
isLoading = true;
});
await FirebaseAuth.instance.signOut();
await googleSignIn.disconnect();
await googleSignIn.signOut();
this.setState(() {
isLoading = false;
});
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => MyApp()),
(Route<dynamic> route) => false);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Chat Screen',
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
),
centerTitle: true,
),
body: WillPopScope(
child: Stack(
children: <Widget>[
// List
Container(
///here the chats users are called
child: StreamBuilder(
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
);
} else {
///THIS IS THE LISTVIEW.BUILDER
return ListView.builder(
padding: EdgeInsets.all(10.0),
///These are some methods that build the containers list with the users information
itemBuilder: (context, index) =>
buildItem(context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
},
),
),
// Loading
Positioned(
child: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(themeColor)),
),
color: Colors.white.withOpacity(0.8),
)
: Container(),
)
],
),
// onWillPop: onBackPress,
),
);
}
Widget buildItem(BuildContext context, DocumentSnapshot document) {
if (document['id'] == currentUserId) {
return Container();
} else {
return Container(
child: FlatButton(
child: Row(
children: <Widget>[
Material(
child: document['profileImageUrl-'] != null
? CachedNetworkImage(
placeholder: (context, url) => Container(
child: CircularProgressIndicator(
strokeWidth: 1.0,
valueColor:
AlwaysStoppedAnimation<Color>(themeColor),
),
width: 50.0,
height: 50.0,
padding: EdgeInsets.all(15.0),
),
//i just cange this
imageUrl: document['profileImageUrl'],
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
)
: Icon(
Icons.account_circle,
size: 50.0,
color: greyColor,
),
borderRadius: BorderRadius.all(Radius.circular(25.0)),
clipBehavior: Clip.hardEdge,
),
Flexible(
child: Container(
child: Column(
children: <Widget>[
Container(
child: Text(
'Name: ${document['nickname']}',
style: TextStyle(color: primaryColor),
),
alignment: Alignment.centerLeft,
margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 5.0),
),
Container(
child: Text(
'email: ${document['email']}',
style: TextStyle(color: primaryColor),
),
alignment: Alignment.centerLeft,
margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 5.0),
),
Container(
child: Text(
'About me: ${document['aboutMe'] ?? 'Not available'}',
style: TextStyle(color: primaryColor),
),
alignment: Alignment.centerLeft,
margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 0.0),
)
],
),
margin: EdgeInsets.only(left: 20.0),
),
),
],
),
onPressed: () {
///here is the flat button to go to messages
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Chat(
peerId: document.documentID,
peerAvatar: document['photoUrl'],
),
),
);
},
color: greyColor2,
padding: EdgeInsets.fromLTRB(25.0, 10.0, 25.0, 10.0),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
),
margin: EdgeInsets.only(bottom: 10.0, left: 5.0, right: 5.0),
);
}
}
}
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
If you want each item in the ListView.builder to be 'tappable' and send you to a profile screen containing the tapped user's information, try wrapping each ListView element in a GestureDetector:
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
GestureDetector(
onTap: Navigator.push(context,
MaterialPageRoute(builder: (context) => UserProfile(user_name, user_age, user_etc)),);
child: buildItem(context, snapshot.data.documents[index])
),
);
You can pass info from your Stream into a newly made UserProfile (or something to that effect) page, which is navigated to by tapping on either of the ListView panels.
Alternatively, in your buildItem widget definition, you can return a GestureDetector (which will wrap your current Container) instead and place the onTap logic in there.

Flutter Navigator push data from firebase

We are trying to get data from firebase which we have currently being rendered within a grid view, but I want to be able to click on the item within the grid view and read more about it.
This is what I have so far and the error I am getting in VS
The argument type 'DocumentSnapshot' can't be assigned to the parameter type 'Merchant'.
HomeScreen
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:paylaterapp/screens/GridMerchantDetails.dart';
Future<void> main() async {
final FirebaseApp app = await FirebaseApp.configure(
name: 'BNPL',
options: const FirebaseOptions(
googleAppID: '***',
gcmSenderID: '***',
apiKey: '***',
projectID: '***',
),
);
final Firestore firestore = Firestore(app: app);
await firestore.settings(timestampsInSnapshotsEnabled: true);
}
class HomeScreen extends StatelessWidget {
HomeScreen(this.firestore);
final Firestore firestore;
CollectionReference get merchants => firestore.collection("merchants");
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stores'),
),
body: _gridView(),
);
}
Widget _gridView() {
return StreamBuilder<QuerySnapshot>(
stream: firestore.collection('merchants').orderBy('name', descending: false).snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
final int merchantCount = snapshot.data.documents.length;
return GridView.builder(
scrollDirection: Axis.vertical,
itemCount: merchantCount,
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemBuilder: (_, int index) {
final DocumentSnapshot document = snapshot.data.documents[index];
final dynamic logo = document['logo_url'], mainImage = document['main_image_url'];
return
CupertinoButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GridMerchantDetails(document),
),
);
},
child: (
Container(
height: 300,
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey,
image: DecorationImage(
image: new NetworkImage(mainImage != null ? mainImage.toString() : 'https://images.unsplash.com/photo-1446844805183-9f5af45f89ee',
)
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Image.network(logo != null ? logo.toString() : 'https://images.unsplash.com/photo-1446844805183-9f5af45f89ee',
width: 220,
fit: BoxFit.fill,
)
]
)
)
)
);
},
);
},
);
}
}
class GridMerchantDetails extends StatelessWidget {
final Merchant merchant;
GridMerchantDetails(this.merchant);
#override
Widget build(BuildContext context) {
return Scaffold(
primary: true,
appBar: AppBar(
title: Text(merchant.name),
),
backgroundColor: Colors.deepPurpleAccent,
body: ListView(
children: <Widget>[
HeaderBanner(this.merchant),
Container(
padding: const EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 20.0),
child: Text(
merchant.desc,
style: TextStyle(
fontSize: 13.0,
color: Colors.white,
),
),
),
],
),
);
}
}

Getting data from cloud firestore onto a listview in flutter

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()
);
}),
);
}
}
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.

Resources