how to search through all documents for a specific field value
for eg: if i want the field: blood_group 'A+' from all documents and show me all documents which has 'A+' in it
https://i.stack.imgur.com/0IhT9.png
https://i.stack.imgur.com/4tkEG.png
source code
You can use the .where filter on the collection reference's query like below:
final QuerySnapshot querySnapshot = await FirebaseFirestore.instance.collection('users').where('blood_group', isEqualTo: 'A+').get();
final List<QueryDocumentSnapshot> documentSnapshotList = querySnapshot.docs;
for (QueryDocumentSnapshot snapshot in documentSnapshotList) {
print(snapshot.data());
}
You can use the .where option. Based on your firebase structure in the picture, you can use the following code, to get a list of all documents that satisfy your request.
Future<QuerySnapshot> bloodgroup (String bloodGroup) async {
return await FirebaseFirestore.instance.collection('Donation').where('blood_group', isEqualTo: bloodGroup).get();
}
void getDocs() async {
QuerySnapshot allResults = await bloodgroup('A+');
for (var item in allResults){
print(item.id); //this will print the id of all the documents which are A+.
}
}
Related
My below code is returning an empty list, even though it SHOULD return data corresponding to my data stored in my firestore database. Also to note: The otherUserId print statement is not getting printed. How can I fix this issue?
Future<List<String>> getChattingWith(String uid) async {
List<String> chattingWith = [];
try {
// create list of all users user is chatting with
final rooms = await FirebaseFirestore.instance
.collection('rooms')
.where('users', arrayContains: uid)
.get();
for (final room in rooms.docs) {
final users = room['users'] as Map<String, dynamic>;
final otherUserId = users['uid1'] == uid ? users['uid2'] : users['uid1'];
print("otherUserId999: $otherUserId");
chattingWith.add(otherUserId);
}
print("chattingWith: $chattingWith");
return chattingWith;
} catch (error) {
print("error: $error");
return [];
}
}
This part of your code does not match your data structure:
final rooms = await FirebaseFirestore.instance
.collection('rooms')
.where('users', arrayContains: uid)
.get();
Your users is a Map and not an array, so arrayContains won't work here. As said in my answer to your previous question, you have to use dot notation to test nested fields:
final rooms = await FirebaseFirestore.instance
.collection('rooms')
.where('users.uid1', isEqualTo: uid)
.where('users.uid2', isEqualTo: otherValue)
.get();
That 👆 is closest to what you tried in your previous question: Firestore conditional array query. It performs an AND condition on the uid1 and uid2 subfields of users.
If instead you want to get all rooms that the user is a participant in, you need an (additional) field that is an array with the UIDs of all participants.
participantUIDs: ["uid1", "uid2"]
Then you can do:
final rooms = await FirebaseFirestore.instance
.collection('rooms')
.where('participants', arrayContains: uid)
.get();
In my flutter app I need to update my current user data but I have this issue [cloud_firestore/not-found] Some requested document was not found. how can I fix this
here my updateData() code
void updateData() {
final FirebaseAuth auth = FirebaseAuth.instance;
final User user = auth.currentUser;
final uid = user.uid;
FirebaseFirestore.instance.
collection('users').
doc(uid).
update({"height": heightTextEditingController.text}).
catchError((e) {
print(e);
});
}
Take a screenshot of your Firestore so that we can see what's your Firestore directory names. Could be a spelling mistake.
Edit 1:
Found the mistake. It should be FirebaseFirestore.instance.collection('users') instead of ('user'). See below codes
FirebaseFirestore.instance.
collection('users').
doc(uid).
update({"height": heightTextEditingController.text}).
catchError((e) {
print(e);
});
}
You need to add the uid as a document id when saving data to the database:
var firestoreInstance = FirebaseFirestore.instance;
var firebaseUser = FirebaseAuth.instance.currentUser;
firestoreInstance.collection("users").doc(firebaseUser.uid).set(
{
"name" : "john",
"email" : "example#example.com",
"height": 180
"weight":70
}).then((_){
print("success!");
});
Inside doc() pass the uid and then use set() to add the fields to the document.
This code is running fine with futurebuilder and i m getting a listview properly.
But i want to see into the documents n print the details in console. I m not getting any idea about how to do this with QuerySnapshot variable.
Future getP() async {
var firestore = Firestore.instance;
var q = await firestore.collection('place_list').getDocuments();
print(q.documents);
return q.documents;
}
I think I have to call it n wait for the responses then print them, can anyone guide me how to do it?
List<Map<String, dynamic>> list =
q.documents.map((DocumentSnapshot doc){
return doc.data;
}).toList();
print(list);
Though the answer is right the current firebase API has changed drastically now to access QuerySnapshot one can follow the below code.
FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) => {
querySnapshot.docs.forEach((doc) {
print(doc["first_name"]);
});
});
And if you are using async/await then first you need to resolve the AsyncSnapshot and then work on it. If you like:
return FutureBuilder(
future: PropertyService(uid:userId).getUserProperties(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.connectionState == ConnectionState.done) {
snapshot.data.docs.forEach((element) {
Property property = Property.fromJson(element.data());
});
return Text("Demo Text");
}
return LoadingPage();
}
);
taken from url
//But I am not getting all the documents present in my firestore DB collection. The first 10 or so entries are getting printed in the console. //
I think that is standard behavior. If you have one million records it can't print everything in console. To check any particular set of documents you have to filter through where condition in query.
If you have still this problem, I hope this will help you.
This is how I get data from QuerySnapshot:
QuerySnapshot snapshot =
await userCollection.where("uid", isEqualTo: uid).get();
List<Object?> data = snapshot.docs.map((e) {
return e.data();
}).toList();
Map<dynamic, dynamic> userData = data[0] as Map;
print(userData["email"]);
Or you can easily get data by:
QuerySnapshot querySnapshot =
await userCollection.where("uid", isEqualTo: uid).get();
print(querySnapshot.docs[0)['fieldName']);
I have a collection of following;
I want to return every company in ascending order by companyName and this is how I'm trying;
QuerySnapshot usersComp = await _firestore
.collection('companies')
.where('belongsTo', isEqualTo: curruser.uid)
.orderBy({
'properties': {'companyName'}
}, descending: false).getDocuments();
Code doesn't give any errors but it also doesn't return any value as well. The statement without orderBy works fine.
How can I write a this orderBy in a working way?
edit
This is the whole getCompanies function in FirebaseCrud:
Future<List<Company>> getCompanies() async {
FirebaseUser curruser = await _authService.getCurrentUser();
DocumentSnapshot userSnapshot = await Firestore.instance
.collection('users')
.document(curruser.uid)
.get();
List partners = userSnapshot.data['partners'];
print('partners');
print(partners[0]);
QuerySnapshot usersComp = await _firestore
.collection('companies')
.where('belongsTo', isEqualTo: curruser.uid)
//.orderBy('properties.companyName', descending: false) // code works fine without this line but not as expected
.getDocuments();
List<Company> companies = new List<Company>();
usersComp.documents.forEach((f) {
int indexOfthis = usersComp.documents.indexOf(f);
companies.add(new Company(
uid: partners[indexOfthis],
companyName: f.data['properties']['companyName'],
address: f.data['properties']['address'],
paymentBalance: f.data['currentPaymentBalance'],
revenueBalance: f.data['currentRevenueBalance'],
personOne: new Person(
phoneNumber: f.data['properties']['personOne']['phoneNumber'],
nameAndSurname: f.data['properties']['personOne']
['nameAndSurname']),
personTwo: new Person(
phoneNumber: f.data['properties']['personTwo']['phoneNumber'],
nameAndSurname: f.data['properties']['personTwo']
['nameAndSurname']),
));
});
return companies;
}
Use dot notation to reference properties of objects to use for sorting.
_firestore
.collection('companies')
.where('belongsTo', isEqualTo: curruser.uid)
.orderBy('properties.companyName'),
descending: false)
I created a collection with a few documents, each have a top-level field and a nested field. If I then run a query over it like this:
Firestore.instance.collection("59739861")
.where("location", isEqualTo: "Bay Area")
.orderBy("properties.companyName", descending: false)
.getDocuments().then((querySnapshot) {
print("Got ${querySnapshot.documents.length} documents");
querySnapshot.documents.forEach((doc) {
print("${doc.documentID}: ${doc.data['properties']}");
});
});
I have added these three documents in my database:
location: "Bay Area", properties.companyName: "Google"
location: "Bay Area", properties.companyName: "Facebook"
location: "Seattle", properties.companyName: "Microsoft"
With the above query, I get the following output printed:
flutter: KJDLLam4xvCJEyc7Gmnh: {companyName: Facebook}
flutter: TMmrOiKTYQWFBmJpughg: {companyName: Google}
I have no idea why you're getting different output.
Just in case it matters, I run the app in an iOS simulator and use this version of the Firestore plugin:
cloud_firestore: ^0.13.0+1
I trying to get the new created document id after data has been stored to firebase database, but get error
E/flutter (20333): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method 'listen' was called on null.
E/flutter (20333): Receiver: null
E/flutter (20333): Tried calling: listen(Closure: (String) => void)
send_data_bloc
_repository
.addOrder(order)
.listen((documentId) => print(documentId));
repository
#override
Observable<String> addOrder(Order order) {
var a = endpoints.collectionEndpoint.add(order.toJson());
a.then((val) {
return Observable.fromFuture(val.documentID());
});
endpoints
#override
get collectionEndpoint => _firestore
.collection(collectionName)
.document(this.id)
.collection(orderCollectionName);
Ideally you should return the future from the repository and await for the future on the bloc. Let me try to give a full code snippet here. It would be something like this:
send_data_bloc
final documentId = await _repository
.addOrder(order);
print(documentId);
return documentId;
repository
#override
Future<String> addOrder(Order order) {
return endpoints.collectionEndpoint.add(order.toJson());
endpoints
#override
get collectionEndpoint => _firestore
.collection(collectionName)
.document(this.id)
.collection(orderCollectionName);
Here
a.then((val) {
return Observable.fromFuture(val.documentID());
});
you are returning the observable within the then function, i believe this is not the expected behavior.
One thing you should do to improve your code quality and readability is to just user async/await. The function on the repository can be rewrited like that:
#override
Observable<String> addOrder(Order order) async {
var documentID = await endpoints.collectionEndpoint.add(order.toJson());
return Observable.fromFuture(val.documentID());
Try this. This should do the trick.
Whats the reason why you are using Observables? Is this a firebase thing?
You could adjust to:
final var documentId = await _repository.addOrder(order);
print(documentId)
i had the same problem here is a snippet of how i approached it
//notice im using add while referencing the document reference
final DocumentReference documentReference=await Firestore.instance.collection('jobs').add({
'jobid':"",
});
then get your id from documentReference
final String jobIdd=documentReference.documentID;
after getting the id now you can add your document to cloud firestore
Firestore.instance.collection('jobs').document(jobIdd).setData({
'category': category,
'description': description,
'datePosted': formattedDate,
'postedby': userid,
'jobid':jobIdd,
});