简体   繁体   English

检查 Firebase Firestore 中是否存在密钥

[英]Check if key exists in Firebase Firestore

I want to make a to-do list with task due date as an optional field, so I need to check if some tasks have dueDate and add it as a subtitle based on that.我想将任务到期日期作为可选字段制作一个待办事项列表,因此我需要检查某些任务是否具有到期日期并基于此将其添加为副标题。 How can I check if a field exists inside a doc in a StreamBuilder?如何检查 StreamBuilder 的文档中是否存在字段?

class _TaskListState extends State<TaskList> {
  var myStream;
  @override
  void initState() {
    myStream = FirebaseFirestore.instance
        .collection('tasks')
        .doc(widget.uid)
        .collection('mytasks')
        .snapshots();

    super.initState();
  }

  ...

  void _updateTaskDesc(
      dynamic currTask, String newDesc, DateTime newDate, TimeOfDay newTime) {
    FirebaseFirestore.instance
        .collection('tasks')
        .doc(widget.uid)
        .collection('mytasks')
        .doc(currTask['id'])
        .update({
      'desc': newDesc,
      'dueDate': newDate.toString(),
      'dueTime': newTime.toString(),
    });
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: myStream,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(
            child: SizedBox(
                height: 100, width: 100, child: CircularProgressIndicator()),
          );
        } else {
          final docs = snapshot.data.docs;
          bool hasDateTime = ????? <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
          return ListView.builder(
            itemCount: docs.length,
            itemBuilder: (ctx, index) {
              final currTask = docs[index];
              return InkWell(
                highlightColor: Theme.of(context).secondaryHeaderColor,
                splashColor: Theme.of(context).secondaryHeaderColor,
                onLongPress: () {
                  showModalBottomSheet<dynamic>(
                    isScrollControlled: true,
                    context: context,
                    builder: (bCtx) {
                      FocusManager.instance.primaryFocus?.unfocus();
                      return TaskOptions(_updateTaskDesc,
                          () => _updateHasImage(docs[index]), currTask);
                    },
                  );
                },
                child: Dismissible(
                  direction: DismissDirection.startToEnd,
                  key: UniqueKey(),
                  onDismissed: (_) async {
                    FirebaseFirestore.instance
                        .collection('tasks')
                        .doc(widget.uid)
                        .collection('mytasks')
                        .doc(currTask['id'])
                        .delete();

                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(
                        content: Text("${currTask['desc']} dismissed"),
                        action: SnackBarAction(
                          label: 'Undo',
                          onPressed: () {
                            FirebaseFirestore.instance
                                .collection("tasks")
                                .doc(widget.uid)
                                .collection("mytasks")
                                .doc(currTask['id'])
                                .set({
                              "desc": currTask['desc'],
                              "id": currTask['id'],
                              "isDone": currTask['isDone'],
                              "hasImage": currTask['hasImage'],
                            });
                            try {
                              FirebaseFirestore.instance
                                  .collection("tasks")
                                  .doc(widget.uid)
                                  .collection("mytasks")
                                  .doc(currTask['id'])
                                  .update({
                                "dueDate": currTask['dueDate'],
                                "dueTime": currTask['dueTime'],
                              });
                            } catch (e) {}
                          },
                        ),
                      ),
                    );
                  },
                  child: ListTile(
                    ...
                    subtitle: Text(hasDateTime
                        ? DateFormat('dd/MM')
                            .format(DateTime.parse(currTask['dueDate']))
                        : ''),
                    ...

I saw that a containsKey('key') method works for some people but I get NoSuchMethod when I try that.我看到containsKey('key')方法适用于某些人,但当我尝试时我得到 NoSuchMethod。 What can I do?我能做些什么?

The single document is just a normal Dart Map , so you can check if a key exists or not using containsKey method.单个文档只是一个普通的 Dart Map ,因此您可以使用containsKey方法检查密钥是否存在。

So you condition becomes the following:所以你的条件变成了以下:

bool hasDateTime = currTask.containsKey('dueDate`);

NOTE: In the question I can see that you are defining the condition in the wrong place which is outside the itemBuilder method in the ListView so that it is not item based and well not work because it does not make sense.注意:在问题中,我可以看到您在ListViewitemBuilder方法之外的错误位置定义条件,因此它不是基于项目的,并且由于没有意义而无法正常工作。

You can have it in this place:你可以在这个地方拥有它:

...
itemBuilder: (ctx, index) {
    final currTask = docs[index];
    bool hasDateTime = currTask.containsKey('dueDate`);
    return InkWell(
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM