I'm trying to retrieve a field from my firestore database. When a user is logged in, I am able to get his/her uid, but I have another collection called restaurants, where inside I have documents of added restaurants. Each restaurant has the UID also included. What I'm trying to do, is to retrieve the data of the restaurant and specifically that one that has the field uid equal to the logged in user.
this is the structure that I have of the database:
So I'm trying to return a ListTile
which will provide the user options to edit the owned restaurant, and then another ListTile
of added meals.
The ListTile
looks like this:
The problem is that I can't find the correct way on how to retrieve those fields
My code:
@override
Widget build(BuildContext context) {
Stream<QuerySnapshot> _restaurantStream = FirebaseFirestore.instance
.collection('restaurant')
.where(uid, isEqualTo: user.uid)
.snapshots();
return StreamBuilder<QuerySnapshot>(
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return LoadingScreen();
}
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Overview'),
),
body: ListView(
shrinkWrap: true,
children: snapshot.data.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data() as Map<String, dynamic>;
Future<void> editRestaurant() async {
final isValid = _form1.currentState.validate();
{
if (!isValid) {
return;
}
}
if (isValid) {
_form1.currentState.validate();
User user = _auth.currentUser;
Restaurant _restaurant = Restaurant(
name: _name,
preparationTime:
double.parse(_preparationEditingController.text),
deliveryFee: double.parse(_feeEditingController.text),
uid: user.uid,
);
// Call the user's CollectionReference to add a new user
await FirebaseFirestore.instance
.collection('restaurant')
.doc(data['rid'])
.update(_restaurant.toMap())
.then((_) => print(uid))
.catchError((error) =>
print("Failed to edit restaurant: $error"));
print('restaurant Edited');
}
}
return Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Card(
color: Colors.white70,
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title: const Text(
'Edit your restaurant',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
// subtitle: Text(DateFormat('dd.MM.yyyy hh:mm').format(widget.order.dateTime)),
trailing: IconButton(
icon: Icon(_expanded
? Icons.expand_less
: Icons.expand_more),
onPressed: () {
setState(() {
_expanded = !_expanded;
});
},
),
),
if (_expanded)
Container(
padding: EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
child: Form(
key: _form1,
child: ListView(
shrinkWrap: true,
children: [
Row(
children: [
Text('Name: '),
Expanded(
child: TextFormField(
onSaved: (val) =>
_nameEditingController
.text = val,
onChanged: (val) {
_name = val;
},
decoration:
const InputDecoration(
counterText: ''),
// controller: _nameEditingController,
maxLength: 20,
initialValue: data['name'],
textInputAction:
TextInputAction.next,
validator: (value) {
if (value.isEmpty) {
return 'Please provide a name';
}
return null;
},
),
),
],
),
Row(
children: [
Text('Prep Time: '),
Expanded(
child: TextFormField(
onSaved: (val) =>
_preparationEditingController
.text = val,
// controller: _nameEditingController,
maxLength: 5,
initialValue:
data['preparationTime']
.toString(),
decoration:
const InputDecoration(
counterText: ''),
textInputAction:
TextInputAction.next,
keyboardType:
TextInputType.number,
// onFieldSubmitted: (_) {},
// onEditingComplete: () {},
validator: (value) {
if (value.isEmpty) {
return 'Please enter a number';
}
if (double.tryParse(value) ==
null) {
return 'Please enter a valid number';
}
if (double.parse(value) <=
0) {
return 'Please enter a greater number';
}
return null;
},
),
),
],
),
Row(
children: [
Text('Delivery Fee: '),
Expanded(
child: TextFormField(
onSaved: (val) =>
_feeEditingController.text =
val,
// controller: _nameEditingController,
maxLength: 5,
initialValue:
data['deliveryFee']
.toString(),
decoration:
const InputDecoration(
counterText: ''),
textInputAction:
TextInputAction.done,
keyboardType:
TextInputType.number,
// onFieldSubmitted: (_) {},
// onEditingComplete: () {},
validator: (value) {
if (value.isEmpty) {
return 'Please enter a number';
}
if (double.tryParse(value) ==
null) {
return 'Please enter a valid number';
}
if (double.parse(value) <=
0) {
return 'Please enter a greater number';
}
return null;
},
),
),
],
),
SizedBox(
height: 15,
),
ElevatedButton(
onPressed: editRestaurant,
child: const Text('Save changes')),
],
),
),
)
],
),
)
],
),
)
],
);
}).toList(),
),
);
},
stream: _restaurantStream,
);
}
Restaurant Model
import 'package:flutter/material.dart';
import 'menu_item_model.dart';
class Restaurant {
String rid;
String uid;
String name;
List<String> tags;
List<MenuItem> menuItems;
double preparationTime;
double deliveryFee;
Restaurant(
{this.rid,
@required this.uid,
@required this.name,
this.tags,
this.menuItems,
@required this.preparationTime,
@required this.deliveryFee});
//send data to the server
Map<String, dynamic> toMap() {
return {
'rid': rid,
'uid': uid,
'name': name,
'tags': tags,
'menuitems': menuItems,
'preparationTime': preparationTime,
'deliveryFee': deliveryFee,
};
}
// receive data from server
factory Restaurant.fromMap(map) {
return Restaurant(
uid: map['uid'],
rid: map['rid'],
name: map['name'],
menuItems: map['menuItems'],
preparationTime: map['preparationTime'],
deliveryFee: map['deliveryFee'],
);
}
}
Any help would be appreciated. and any suggestions on how to improve the structure to get the data in a simpler way would also be great!