I am working on a simple booking application.
For each booked slot I have a Cancel button, when pressed the appointment should be deleted from the collection.
Future deleteAppt() async {
QuerySnapshot querySnapshot =
await FirebaseFirestore.instance.collection("client_bookings").get();
for (int i = 0; i < querySnapshot.docs.length; i++) {
var a = querySnapshot.docs[i];
final collection =
FirebaseFirestore.instance.collection('client_bookings');
collection
.doc(a.id) // <-- Doc ID to be deleted.
.delete() // <-- Delete
.then((_) => print('Deleted'))
.catchError((error) => print('Delete failed: $error'));
print(a.id);
}
}
This is my code so far. However, when the button is clicked all appointments are deleted. Could you give me any advice how can i fix this?
In addition, I am using a StreamBuilder and ListView.builder to iterate though the collection and display each appointment in a container.
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('client_bookings')
.where("email",
isEqualTo: FirebaseAuth.instance.currentUser?.email)
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
print(snapshot.hasData);
return Text("error");
} else if (snapshot.hasData) {
print(snapshot.hasData);
return ListView.builder(
itemCount: snapshot.data?.docs.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, int i) {
var data = snapshot.data!.docs[i];
var bookingStart = data['bookingStart'];
DateTime bookingStartConverted = DateTime.parse(bookingStart);
if(bookingStartConverted.isAfter(today)) {
print("upcoming");
return Container(
height: height,
width: width,
margin: EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(
20),
boxShadow: [
BoxShadow(
color: Colors.blueGrey
.shade100,
blurRadius: 5,
spreadRadius: 3)
]),
child: Align(
alignment: Alignment.center,
child: Column(children: [
Padding(
padding:
EdgeInsets.only(
left: 15, top: 8),
child: Text(
"Dr. " + data['doctorName'],
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight
.bold,
color: Colors
.blueAccent),
)),
Padding(
padding: EdgeInsets.only(
top: 5),
child: Text(
data['doctorType'],
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 15,
color: Colors.grey),
)),
const Divider(
height: 22,
thickness: 0.4,
color: Colors.grey,
),
Row(
children: [
Icon(Icons
.access_time_outlined),
Expanded(
flex: 1,
child: Text(
data['bookingStart'],
style: TextStyle(
fontSize: 16,
color: Colors
.black87
.withOpacity(
0.5)),
)),
Icon(Icons
.location_on_outlined),
Expanded(
flex: 1,
child: TextButton(
onPressed: () {
opentApptMap();
},
child: Text(
data['hospitalName'],
textAlign: TextAlign
.center,
style: TextStyle(
decoration: TextDecoration
.underline),
)),
)
],
),
Padding(
padding:
const EdgeInsets.only(
top: 5.0),
child: Row(
children: <Widget>[
Expanded(
child: SizedBox(
// width: 80,
height: 30,
child: ElevatedButton(
child: const Text(
"Cancel"),
onPressed: () {
Navigator.of(
context).push(
MaterialPageRoute(
builder: (
context) =>
CancelApptBox()));
},
style:
ElevatedButton
.styleFrom(
shape:
StadiumBorder(),
textStyle: TextStyle(
fontSize: 15,
)),
),
),
),
Padding(
padding:
EdgeInsets.only(
right: 8)),
Expanded(
child: SizedBox(
// width: 80,
height: 30,
child: ElevatedButton(
child:
const Text(
"Reschedule"),
onPressed: () {},
style:
ElevatedButton
.styleFrom(
shape:
StadiumBorder(),
textStyle: TextStyle(
fontSize: 15,
)),
),
),
)
],
))
])),
);
}else{
print("no appts");
}
});
} else {
return Text("else");
}
})
//Cancel appt Box
class CancelApptBox extends StatelessWidget {
const CancelApptBox({super.key});
Future deleteAppt() async {
QuerySnapshot querySnapshot =
await FirebaseFirestore.instance.collection("client_bookings").get();
for (int i = 0; i < querySnapshot.docs.length; i++) {
var a = querySnapshot.docs[i];
final collection =
FirebaseFirestore.instance.collection('client_bookings');
collection
.doc(a.id) // <-- Doc ID to be deleted.
.delete() // <-- Delete
.then((_) => print('Deleted'))
.catchError((error) => print('Delete failed: $error'));
print(a.id);
}
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Are you sure you want to cancel the appointment?'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context, 'Yes');
deleteAppt();
},
child: const Text('Yes',
style: TextStyle(fontWeight: FontWeight.bold)),
),
TextButton(
onPressed: () => Navigator.pop(context, 'Go back'),
child: const Text('Go back'),
),
],
);
}
}
3
Answers
you are iterating over every document and deleting that document
remove the for statement
cancel button
main page
If you want to delete a specific appointment, you should pass appointment id.
If you want to delete a specific value from a collection, you must provide the document id that you want to delete.In above snippet you are providing all document id to delete method.That’s why all docs are being removed from collection.
If you want to delete a specific item, follow the steps below.
1)Get whole collection.
2)Find the id from collection that you want to delete.
3)Pass that id to delete method.
Note:If you already have an ID that needs to be deleted, ignore the "First" point.