skip to Main Content

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.

scheme image added

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'),
        ),
      ],
    );
  }
}

error in the main page

3

Answers


  1. you are iterating over every document and deleting that document

     for (int i = 0; i < querySnapshot.docs.length; i++) {}
    

    remove the for statement

    cancel button

    class CancelApptBox extends StatelessWidget {
    int i;
      const CancelApptBox({super.key,}this.i);
    
      Future deleteAppt() async {
        QuerySnapshot querySnapshot =
            await FirebaseFirestore.instance.collection("client_bookings").get();
    
    
          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'),
            ),
          ],
        );
      }
    }
    
    

    main page

    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(i)));
                                                                },
                                                                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");
                                }
                              })
    
    Login or Signup to reply.
  2. If you want to delete a specific appointment, you should pass appointment id.

    Future<void> deleteAppt(String apptId) async {
      final collection = FirebaseFirestore.instance.collection('client_bookings');
      try {
        await collection.doc(apptId).delete();
        print('Deleted');
      } catch (error) {
        print('Delete failed: $error');
      }
    }
    
    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search