I am trying to retrieve and display a list of items on firebase, I have been able to access everything else on firebase apart from the list itself. I think the issue might be how I am going about retrieving the list because of the method in which it was saved. Here is the order model code
import 'package:butcherbox/models/productsModel.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:meta/meta.dart';
class Order {
Order(
{@required this.items,
//this.theItems,
this.location,
this.orderId,
this.time,
@required this.price});
final List<ProductsModel> items;
final String location;
final int orderId;
final Timestamp time;
final int price;
factory Order.fromMap(Map<String, dynamic> data) {
if (data == null) {
return null;
}
final List<ProductsModel> items = data['items'];
final String location = data['location'];
final int price = data['price'];
final int orderId = data['orderId'];
final Timestamp time = data['time'];
return Order(
items: items,
location: location,
price: price,
orderId: orderId,
time: time,
);
}
Map<String, dynamic> toMap() {
return {
'item': items.map((e) => e.toJson()).toList(),
'location': location,
'orderId': orderId,
'time': time,
'price': price
};
}
}
This is the code to display the data
import 'package:butcherbox/butch_widgets/order_list_tile.dart';
import 'package:butcherbox/models/ordersmodel.dart';
import 'package:butcherbox/services/database.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class Orders extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.green[200],
title: Text(
'Orders',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.green[900]),
),
),
body: _buildContents(context),
);
}
Widget _buildContents(BuildContext context) {
final database = Provider.of<Database>(context, listen: false);
return StreamBuilder<List<Order>>(
stream: database.ordersStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final orders = snapshot.data;
// final children =
// orders.map((order) => Text(order.location)).toList();
final children =
orders.map((order) => OrderListTile(order: order)).toList();
return ListView(children: children);
}
if (snapshot.hasError) {
return Center(child: Text('Some Error Occurred'));
}
return Center(child: CircularProgressIndicator());
});
}
}
This is the widget for the UI
import 'package:butcherbox/models/ordersmodel.dart';
import 'package:flutter/material.dart';
class OrderListTile extends StatelessWidget {
final Order order;
const OrderListTile({Key key, @required this.order}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(
'Order No: ${order.orderId}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.green[900]),
),
trailing: Text(
'Vendor: ${order.location}',
style: TextStyle(fontSize: 16),
),
subtitle: ListView.builder(
itemCount: order.items.length, <-- This is where the error is
shrinkWrap: true,
itemBuilder: (context, i) {
return Expanded(
child: Column(
children: [
Text('${order.items[i].name}'),
Text('${order.items[i].quantity.toString()}')
],
),
);
}),
isThreeLine: true,
);
}
}
This is the database code
import 'package:butcherbox/models/ordersmodel.dart';
import 'package:butcherbox/services/api_path.dart';
import 'package:meta/meta.dart';
import 'package:butcherbox/services/firestore_service.dart';
abstract class Database {
Future<void> createOrder(Order order);
Stream<List<Order>> ordersStream();
}
String docFromId() => DateTime.now().toIso8601String();
class FireStoreDatabase implements Database {
FireStoreDatabase({@required this.uid}) : assert(uid != null);
final String uid;
final _service = FireStoreService.instance;
Future<void> createOrder(Order order) => _service.setData(
//path: APIPath.order(uid, 'orderdetails'), data: order.toMap());
path: APIPath.order(uid, docFromId()),
data: order.toMap(),
);
Stream<List<Order>> ordersStream() => _service.collectionStream(
path: APIPath.orders(uid), builder: (data) => Order.fromMap(data));
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
class FireStoreService {
FireStoreService._();
static final instance = FireStoreService._();
Future<void> setData({String path, Map<String, dynamic> data}) async {
final reference = FirebaseFirestore.instance.doc(path);
print('$path: $data');
await reference.set(data);
}
Stream<List<T>> collectionStream<T>({
@required String path,
@required T Function(Map<String, dynamic> data) builder,
}) {
final reference = FirebaseFirestore.instance.collection(path);
final snapshots = reference.snapshots();
return snapshots.map((snapshot) => snapshot.docs
.map(
(snapshot) => builder(snapshot.data()),
)
.toList());
}
}