英文:
Delete a document from firebase 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) // <-- 要删除的文档 ID。
.delete() // <-- 删除
.then((_) => print('已删除'))
.catchError((error) => print('删除失败:$error'));
print(a.id);
}
}
到目前为止,这是我的代码。但是,当点击按钮时,所有预约都被删除。您能给我一些建议,我如何修复这个问题吗?
此外,我正在使用StreamBuilder和ListView.builder来迭代集合并在容器中显示每个预约。
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("错误");
} 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("即将到来");
return Container(
// 这里是容器的描述和构建
// ...
);
} else {
print("没有预约");
}
});
} else {
return Text("其他情况");
}
}
)
// 取消预约对话框
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) // <-- 要删除的文档 ID。
.delete() // <-- 删除
.then((_) => print('已删除'))
.catchError((error) => print('删除失败:$error'));
print(a.id);
}
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('您确定要取消预约吗?'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context, '是的');
deleteAppt();
},
child: const Text('是的',
style: TextStyle(fontWeight: FontWeight.bold)),
),
TextButton(
onPressed: () => Navigator.pop(context, '返回'),
child: const Text('返回'),
),
],
);
}
}
希望这些翻译对您有所帮助。如果您有任何进一步的问题,欢迎提出。
英文:
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'),
),
],
);
}
}
答案1
得分: 2
如果您想要删除特定的预约,您应该传递预约 ID。
Future<void> deleteAppt(String apptId) async {
final collection = FirebaseFirestore.instance.collection('client_bookings');
try {
await collection.doc(apptId).delete();
print('已删除');
} catch (error) {
print('删除失败:$error');
}
}
英文:
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');
}
}
答案2
得分: 0
你正在迭代每个文档并删除该文档
for (int i = 0; i < querySnapshot.docs.length; i++) {}
删除for
语句
取消按钮
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) // <-- 要删除的文档ID
.delete() // <-- 删除
.then((_) => print('已删除'))
.catchError((error) => print('删除失败:$error'));
print(a.id);
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('您确定要取消预约吗?'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context, '是的');
deleteAppt();
},
child: const Text('是的',
style: TextStyle(fontWeight: FontWeight.bold)),
),
TextButton(
onPressed: () => Navigator.pop(context, '返回'),
child: const Text('返回'),
),
],
);
}
}
主页
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("错误");
} 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("即将到来");
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(
"取消"),
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(
"重新预约"),
onPressed: () {},
style:
ElevatedButton
.styleFrom(
shape:
StadiumBorder(),
textStyle: TextStyle(
fontSize: 15,
))),
),
)
],
))
])),
);
}else{
print("没有预约");
}
});
} else {
return Text("其他情况");
}
})
英文:
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");
}
})
答案3
得分: 0
如果您想从集合中删除特定数值,您必须提供要删除的文档标识符。在上面的代码片段中,您正在提供所有文档标识符来执行删除操作,这就是为什么所有文档都被从集合中删除的原因。
如果您想删除特定项,请按照以下步骤操作:
- 获取整个集合。
- 从集合中找到要删除的标识符。
- 将该标识符传递给删除方法。
注意:如果您已经有一个需要删除的标识符,请忽略“第一”点。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论