Firebase 如何使用表单验证验证集合Firestore中是否存在带颤振的文档

Firebase 如何使用表单验证验证集合Firestore中是否存在带颤振的文档,firebase,flutter,dart,google-cloud-firestore,Firebase,Flutter,Dart,Google Cloud Firestore,我想使用表单验证来验证Firestore集合中的文档是否存在。如果没有,我将向用户返回一个带有错误消息的字符串。用户只能在填写数据库中已存在的名称后才能继续操作(否则他们无法订阅正确的环境)。 我正在使用表单和文本表单字段以及代码中的验证器 下面我将我的有状态小部件与表单 import 'package:flutter/material.dart'; import 'package:modal_progress_hud/modal_progress_hud.dart'; class Build

我想使用表单验证来验证Firestore集合中的文档是否存在。如果没有,我将向用户返回一个带有错误消息的字符串。用户只能在填写数据库中已存在的名称后才能继续操作(否则他们无法订阅正确的环境)。 我正在使用
表单
文本表单字段
以及代码中的验证器

下面我将我的
有状态小部件
表单

import 'package:flutter/material.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';

class BuildingScreen extends StatefulWidget {

  @override
  _BuildingScreenState createState() => _BuildingScreenState();
}

class _BuildingScreenState extends State<BuildingScreen> {
  final _formKey = GlobalKey<FormState>();
  bool showSpinner = false;
  String environment;
  bool _autoValidate = false;

  void _validateInputs() {
    if (_formKey.currentState.validate()) {
      _formKey.currentState.save();
      setState(() {
        showSpinner = true;
      });
    } else {
      setState(() {
        _autoValidate = true;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ModalProgressHUD(
        inAsyncCall: showSpinner,
              child: Column(
                children: <Widget>[
                  Form(
                    key: _formKey,
                    child: Column(
                      children: <Widget>[
                        TextFormField(
                          textAlign: TextAlign.center,
                          validator: validateEnvironment,
                          onSaved: (String value) {
                            environment = value;
                          },
                        ),
                        RoundedButton(
// the RoundedButton is just a material button with some custom padding
                          buttonTitle: 'Verify',
                          onPressed: () async {
                            _validateInputs();

                            try {
                              if (_formKey.currentState.validate()) {
                                Navigator.pushNamed(
                                    context, RoosterEnvironment.id);
                              }
                              setState(() {
                                showSpinner = false;
                              });
                            } catch (e) {
                              print(e);
                            }
                          },
                        ),
                      ],
                    ),
                  ),
                ],
              ),
      ),
    );
  }
}

在我的firestore数据库中,我有一个名为“环境”的集合。在这个集合中,我保存了一个名为“test”的文档,其字段为“name:test”。现在
(value!=Firestore.instance.collection('environments').document(value.documentID)
将始终为false,因为Firestore实例返回插入
TextFormField
中的任何值。当我将其替换为
(value!=“test”)
时,验证器工作正常。我还尝试将集合命名为“test”,然后验证它是否存在,如下所示:
(value!=Firestore.instance.collection('test'))
,但这将返回“collectionReference”的实例

我想知道是否有可能对表单验证进行检查,或者是否应该以完全不同的方式进行检查?在此方面的任何帮助都将不胜感激

更新

多亏了一些帮助,我更新了代码。现在,我使用
TextEditingController
和G Griffo的代码来检查文本字段中的值是否存在于Firestore中。当错误消息还不存在时,我还没有添加错误消息,但下面我包含了适用于我的代码

final _controller = TextEditingController();

static Future<bool> validateEnvironment(String docID) async {
    bool exists = false;
    try {
      await Firestore.instance
          .document("environments/$docID")
          .get()
          .then((doc) {
        if (doc.exists)
          exists = true;
        else
          exists = false;
      });
      print(exists);
      return exists;
    } catch (e) {
      return false;
    }
  }

  void _formvalidate(String docId) async {
    validateEnvironment(docId).then((value) {
      if (value == true) {
        _updateData();
        Navigator.pushNamed(context, RoosterEnvironment.id);
      } else {
      // do something
      }
    });
  }


再次感谢

我认为Firestore可以查询包含所有文档的所有集合数据,但Firestore不能查询不存在的文档名称。因此,您可以首先接收集合中的所有文档名,然后验证它们。 请试试这个

final snapshots = Firestore.instance.collection('environments').snapshots();

final docNameList = snapshots.map((snapshot) {
  final result = snapshot.documents
      .map((snapshot) =>  snapshot.documentID).toList();
  return result;
});
你可以这样验证

String validateEnvironment(String value) {
   if (!docNameList.data.contains(value))
     return 'Environment not on the list';
  else
     return null;
}

如果有错误,请告诉我。

我认为Firestore可以查询包含所有文档的所有收集数据,但Firestore无法查询不存在的文档名称。因此,您可以首先接收集合中的所有文档名,然后验证它们。 请试试这个

final snapshots = Firestore.instance.collection('environments').snapshots();

final docNameList = snapshots.map((snapshot) {
  final result = snapshot.documents
      .map((snapshot) =>  snapshot.documentID).toList();
  return result;
});
你可以这样验证

String validateEnvironment(String value) {
   if (!docNameList.data.contains(value))
     return 'Environment not on the list';
  else
     return null;
}

如果有错误,请告诉我。

您可以尝试通过运行查询来搜索文档ID,以检查您拥有的ID是否已存在于该集合中。我们从一个静态方法开始执行此操作

     static Future<bool> validateEnvironment(String docID) async {
    bool exists = false;
    try {
      await Firestore.instance.document("environments/$docID").get().then((doc) {
        if (doc.exists)
          exists = true;
        else
          exists = false;
      });
      return exists;
    } catch (e) {
      return false;
    }
}

您可以尝试通过运行查询来搜索文档ID,以检查您拥有的ID是否已存在于该集合中

     static Future<bool> validateEnvironment(String docID) async {
    bool exists = false;
    try {
      await Firestore.instance.document("environments/$docID").get().then((doc) {
        if (doc.exists)
          exists = true;
        else
          exists = false;
      });
      return exists;
    } catch (e) {
      return false;
    }
}

也许我应该提到我还是一个颤振初学者。我试着实现你的代码,我想我理解,但当我尝试它时,它没有验证,也就是说,它传递的所有值都是“在列表上”。我试着打印docNameList,然后它给了我一个值“Instance of”\u MapStream“,也许我忘了它是快照。请试一试!docNameList.data.contains(value)也许我应该提到我还是一个颤振初学者。我试着实现你的代码,我想我理解,但当我尝试它时,它没有验证,也就是说,它传递的所有值都是“在列表上”。我试着打印docNameList,然后它给了我一个值“Instance of”\u MapStream“,也许我忘了它是快照。请试一试!docNameList.data.contains(value)谢谢!我不得不更新我的代码一点,但你的回答帮助了我!谢谢我不得不更新我的代码一点,但你的回答帮助了我!