'Flutter firebase validation of form field inputs
I'm new to Flutter and Firebase and I am trying to validate user input from a form and run it up against a the firebase collection.
I ask users to create a username and want to validate that there is not an existing username in my Firebase directory.
I got this validation method from the discussion on Check if Field Already exists in Flutter Firestore. I want to feed the method a name, build a List of documents with that name, and confirm that none exist.
Future<bool> doesNameAlreadyExist(String name) async {
final QuerySnapshot result = await Firestore.instance
.collection('user')
.where('user_id', isEqualTo: name)
.limit(1)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
return documents.length == 1;
}
I hope to be able to call this method within the validator of the text form field as I have done below.
new TextFormField(
decoration: new InputDecoration(labelText: 'Username'),
validator: (value) => doesNameAlreadyExist(value) ? "Username already taken" : null,
onSaved: (value) => _username = value,
),
However, this throws an error that I must have a static type of bool for the validator.
My question: how can I (1) create a static boolean method that would be able to search Firebase or (2) how can I get the same functionality with the async call (ideally, without having to build another widget)?
Solution 1:[1]
Old question but found that the current answer wasn't working for me, as since the doesNameAlreadyExist(user) function returns a future, then the value of _userExist will return prior to evaluating the then() callback.
I found suggestions elsewhere to use the onChanged event to track and update the status of the async validation you need to do, then check that in the validator handler which has to be a synchronous function. So something like this:
// somewhere above the build function
bool _nameAlreadyExists = false;
bool _autoValidate = false;
Future<void> setNameExists(String name) async {
bool _nameAlreadyExists = await yourAsyncFunctionForDoingTheCheckHere(name);
}
// inside your build function when defining the Form
Form(
key: _formKey,
autovalidateMode: _autoValidate ? AutovalidateMode.onUserInteraction : AutovalidateMode.disabled, ...
// your TextFormField
TextFormField(
validator: (value) => (value == null || value.isEmpty ? "Name is required"
: (_nameAlreadyExists ? "Name already in use." : null)),
onChanged: (txt) => setNameExists(txt), ...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | David Ferraro |
