我有一个名为 company
的收藏集。
所有公司都将像我的屏幕快照中那样存储。
添加其他公司时,我想检查 name
是否已经存在。
如何执行?
“ Nova”和“ Tradetech”是两家公司。
当我尝试再次在字段name: "nova"
中添加“ Nova” 时,我想显示一条通知:“公司已经存在!” 。 / p>
答案 0 :(得分:5)
我已经通过以下代码解决了此问题,感谢您的帮助!
在我用来查找的以下代码中
1)是否存在文档?
2)键是否存在?
3)值是否存在?
SIMPLE METHOD
//////////////////////////////////////////////////////////////////////
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
String myText1 = 'temp1';
String myText2 = 'temp2';
String myText3 = 'temp3';
String myText4 = 'temp4';
String myText5 = 'temp5';
String myText6 = 'temp6';
StreamSubscription<DocumentSnapshot> subscription;
final DocumentReference documentReference =
Firestore.instance.document("company/Nova");
class Clean extends StatefulWidget {
@override
_CleanState createState() => _CleanState();
}
class _CleanState extends State<Clean> {
@override
void initState() {
super.initState();
subscription = documentReference.snapshots().listen((datasnapshot) {
//FINDING A SPECIFICDOCUMENT IS EXISTING INSIDE A COLLECTION
if (datasnapshot.exists) {
setState(() {
myText1 = "Document exist";
});
} else if (!datasnapshot.exists) {
setState(() {
myText2 = "Document not exist";
});
}
//FINDING A SPECIFIC KEY IS EXISTING INSIDE A DOCUMENT
if (datasnapshot.data.containsKey("name")) {
setState(() {
myText3 = "key exists";
});
} else if (!datasnapshot.data.containsKey("name")) {
setState(() {
myText4 = "key not exists";
});
}
//FINDING A SPECIFIC VALUE IS EXISTING INSIDE A DOCUMENT
if (datasnapshot.data.containsValue("nova")) {
setState(() {
myText5 = "value exists";
});
} else if (!datasnapshot.data.containsValue("nova")) {
setState(() {
myText6 = "value not exists";
});
}
});
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
new Text(myText1),
new Text(myText2),
new Text(myText3),
new Text(myText4),
new Text(myText5),
new Text(myText6),
],
);
}
}
基于我现有代码的旧复杂方法 ///////////////////////////////////////////////////// //////
它有一个搜索栏,当您键入它时将显示公司名称,即是否存在
一个Card
和一个RaisedButton
。我在 Firestore 中使用小写字母,以避免搜索错误。我已将TextFormField
的输出强制为toLowercase()
小写。您可以将其更改为自己的文本格式。
//if the name is not existing it will show a raised button so u can clcik on that to
//go to a COMPANY ADDING PAGE,otherwise it will only show a **CARD** so that you
//can't go to the next page to add your company
//code:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
import './fullscreen.dart';
const blue = 0xFF3b78e7;
String filter = '';
StreamSubscription<DocumentSnapshot> subscription;
final TextEditingController _usercontroller = new TextEditingController();
class CheckAvail extends StatefulWidget {
@override
HomeState createState() => HomeState();
}
class HomeState extends State<CheckAvail> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// CHILD1
new Flexible(
child: StreamBuilder(
stream: Firestore.instance
.collection('company')
.where('name', isGreaterThanOrEqualTo: filter.toLowerCase())
.limit(1)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return new Column(
children: <Widget>[
new Card(
elevation: 5.0,
child: new Image.asset('assets/progress.gif'),
)
],
);
} else {
return FirestoreListView1(documents: snapshot.data.documents);
}
},
),
),
new Card(
elevation: 0.0,
color: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.circular(60.0)),
child: Container(
padding: new EdgeInsets.only(left: 8.0),
child: new TextField(
controller: _usercontroller,
onChanged: (String z) {
setState(() {
filter = z;
});
},
decoration: const InputDecoration(
hintText: "Search...",
hintStyle: TextStyle(
fontFamily: 'roboto',
color: Colors.black38,
fontSize: 16.0,
letterSpacing: -0.500),
fillColor: Colors.white,
border: InputBorder.none,
),
),
),
),
],
),
backgroundColor: Color(blue),
);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class FirestoreListView1 extends StatelessWidget {
final List<DocumentSnapshot> documents;
FirestoreListView1({this.documents});
@override
Widget build(BuildContext context1) {
return ListView.builder(
itemCount: documents.length,
padding: new EdgeInsets.all(1.0),
itemBuilder: (BuildContext context1, int index) {
String name = documents[index].data['name'];
if (name.contains(filter.toLowerCase()) &&
name.length == filter.length) {
return new Container(
padding: new EdgeInsets.only(top: 45.0),
child: new Card(
child: new Text(
"Error:Already a Company Exists with this name\nTry another name")),
);
} else {
return (filter.length >= 1)
? new Container(
padding: new EdgeInsets.only(top: 15.0),
child: new RaisedButton(
onPressed: () => Navigator.push(
context1,
new MaterialPageRoute(
builder: (context1) => new NextPage(
value1: name,
))),
disabledColor: Colors.white,
child: new Text(
"Good!You can use this company name",
),
),
)
: new Container(padding: new EdgeInsets.only(top: 250.0),
child: new Card(child: new Text("CHECK IF YOUR COMPANY NAME \n AVAILABLE OR NOT",style: new TextStyle(fontSize: 20.0),)),
);
}
});
}
}
答案 1 :(得分:4)
您可以简单地使用where
query来仅接收具有name
的文档,然后检查是否获得了文档。这是一个async
示例方法,它将执行您想知道的事情。
Future<bool> doesNameAlreadyExist(String name) async {
final QuerySnapshot result = await Firestore.instance
.collection('company')
.where('name', isEqualTo: name)
.limit(1)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
return documents.length == 1;
}
正如您所看到的,我只是 接收文档,其中name
字段与给定的name
相匹配。我还添加了limit(1)
以确保我不会不必要地检索多于1个文档(这在 theory 中永远不会发生),然后我只是检查是否length
集合中所有文档中的company
等于 1 。如果等于 1 ,则已有 公司具有该名称,否则就没有该名称。
您还可以删除limit(1)
并进行支票documents.length > 1
,这也可以,但是可能会检索不必要的文档。
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: doesNameAlreadyExist('nova'),
builder: (context, AsyncSnapshot<bool> result) {
if (!result.hasData)
return Container(); // future still needs to be finished (loading)
if (result.data) // result.data is the returned bool from doesNameAlreadyExists
return Text('A company called "Nova" already exists.');
else
return Text('No company called "Nova" exists yet.');
},
);
}
在这里,我没有显示错误消息,这也可以通过 example方法轻松实现。但是,使用了某些小部件的build
方法。例如在对话框中工作,但我决定这样做以使其简单易懂。 FutureBuilder
从您的问题中取出doesNameAlreadyExist
,在这种情况下,其名称为“ Nova” ,最后将返回一个Text
小部件,指出是否名称已经存在。
where
查询是区分大小写的。这意味着如果您输入例如“ noVa” 代替“ nova” 。由于这对您可能很重要,因此您可以make use of this nice method,在其中创建不敏感的额外字段,例如所有字母都很小,然后您将像这样简单查询:
.where('name_insensitive', isEqualTo: name.toLowerCase())
答案 2 :(得分:2)
final QuerySnapshot result =
await Firestore.instance.collection('users').where('nickname', isEqualTo:
nickname).getDocuments();
final List < DocumentSnapshot > documents = result.documents;
if (documents.length > 0) {
//exists
} else {
//not exists
}
答案 3 :(得分:0)
我知道我迟到了。 为将来的用户发布。 试试这个:
DocumentReference datab = db.collection("Company").document("Nova");
datab.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if(documentSnapshot.contains("name"))
{
Toast.makeText(YourActivity.this, "Child exixts.", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(YourActivity.this, "Doesnt exits.", Toast.LENGTH_SHORT).show();
}
});