Flutter FireStore: The method 'where' isn't defined for the type 'DocumentReference' - flutter

If I use the code, I can receive the data correctly.
However, using .where, I get the error:
The method 'where' isn't defined for the type 'DocumentReference'.
Try correcting the name to the name of an existing method, or defining a method named 'where'.
code:
chamaBancoDeDados(curso, materia, id, dificuldade) {
Map<String, dynamic> dados = {};
final documentoRef = FirebaseFirestore.instance
.collection('cursos')
.doc(curso)
.collection(materia)
.doc(id)
.where('dificuldade', arrayContainsAny: ['normal']);
documentoRef
.get()
.then((DocumentSnapshot documento) {
if (documento.exists) {
try {
dados = documento.data() as Map<String, dynamic>;
print("dados são: $dados");
} on StateError catch (e) {
print('Erro tentando adquirir o documento no banco de dados: $e');
}
} else {
print('O documento não existe no banco de dados');
}
});
return dados;
}
}
I've already searched a lot on the internet, including the Firebase documentation, but I don't know where I'm going wrong.

Your current code tries to read a single document with a known ID, in which case there is no way to further filter the data with a where clause. So if you only want to read that single document, remove the where:
final documentoRef = FirebaseFirestore.instance
.collection('cursos')
.doc(curso)
.collection(materia)
.doc(id);
If on the other hand, you want to read all documents from the cursos collection with a normal difficulty level, that be done by removing the .doc(id) clause:
final documentoRef = FirebaseFirestore.instance
.collection('cursos')
.doc(curso)
.collection(materia)
.where('dificuldade', arrayContainsAny: ['normal']);

If you see in line 7 of your code, that gets a document from firestore, and you cant use .where() on a document.
.where() is used for collections to check the condition for all documents (in that collection) and return the documents which satisfy the need.
From the above given info, I'd suggest you to remove 7th line of code and try again.
Please share your Firestore hierarchy so that we could suggest a better way to perform your queries.

I make this and works how I wanted:
final teste = FirebaseFirestore.instance
.collection('cursos')
.doc(curso)
.collection(materia)
.where('dificuldade', arrayContainsAny: [dificuldade]);
await teste
.get()
.then((event) {
print("${doc.id} => ${doc.data()}");
}
}, onError: (e) => print("Error completing: $e"));

Related

Why is vs code saying the method '.getDocuments' and the getter documents are not defined for types Query and QuerySnapshot respectively?

void _getQuestions() async {
// Query Firestore for questions with the specified tags
Query query = await _firestore
.collection('questions')
.where('tags', arrayContainsAny: widget.tags);
QuerySnapshot querySnapshot = await query.getDocuments();
setState(() {
_questions = querySnapshot.documents;
});
importing cloud_firestore.dart.
I expected the errors to leave, but they are still around.
The method to get the documents is called get() in Flutter, not getDocuments().
I recommend keeping the Firebase documentation handy for this sort of thing, for this case that'd be the section on getting multiple documents from a collection

How to correctly fetch data from firebase using where clauses and custom filters from firebase using flutter

Im trying to fetch data using
Stream<List<User>> getUsers(User user) {
return _firebaseFirestore
.collection('users')
// .where('interestedIn', isEqualTo: _selectInterest(user))
.snapshots()
.map((snap) {
return snap.docs.map((doc) => User.fromSnapshot(doc)).toList();
});
}
The filter used in the where clause is as follows
_selectInterest(User user) {
if (user.interestPreference == null) {
return ['HIRING', 'WORK'];
}
return user.interestPreference;
}
In firebase I store interestPreference as an Array with 'HIRING' as the only element in the current user's data, when I try to fetch users with 'HIRING' in their interestedIn which is a string I dont get any data. But when I hardcode the where clause as
.where('interestedIn', isEqualTo: 'HIRING')
I get the data, Can anyone help me solve my dilemma?
From that last query, it sounds like the interestedIn field in your database is a single string value, like interestedIn: "HIRING".
Your current query returns documents where interestedIn is an array with exactly the two values you specify, so interestedIn: ['HIRING', 'WORK']
If you want to return all documents where interested in is either "HIRING" or "WORK", you can use an IN condition:
.where('interestedIn', whereIn: ['HIRING', 'WORK'])
Or with your helper function:
.where('interestedIn', whereIn: _selectInterest(user))

flutter firestore how I filter data

I have a collection (Groups) inside it
fields contain information about users who joined the group,
I want to display to the user all groups he joined.
List groupList = [];
void getAvailableGroups() async {
await _fireStore
.collection('Groups')
.get()
.then((value) {
groupList = value.docs;
});
}
I tried to convert from map into array but it gives me array within map this is my code
Future createGroup() async{
GroupRoomModel newGroup = GroupRoomModel(
groupName: groupName.text,
groupRoomId: uuid.v1(),
owner: userModel.uid,
membersList: controller.membersList,
membersListUid: controller.membersListUid.cast() // like this
);
}
...
Also I tried
Future createGroupFunc() async{
GroupRoomModel newGroup = GroupRoomModel(
groupName: groupName.text,
groupRoomId: uuid.v1(),
owner: userModel.uid,
membersList: controller.membersList,
membersListUid: controller.membersListUid.map((e)=> e).toList()
);
...
It might be tempting to try filtering based on something like this:
_fireStore
.collection('Groups')
.where('membersList', arrayContains: 'test#email.com')
This won't work though, as arrayContains only finds something a match when it matches a complete item in the array. You can't use arrayContains to match just a subset of an item.
The common solution is to add an additional array field to your documents with just the property you want to be able to query on. For example:
memberEmails: ['test#email.com', 'test#example.com']
With such an addition field, you can query with:
_fireStore
.collection('Groups')
.where('memberEmails', arrayContains: 'test#email.com')

Get all documents from a Firestore collection in Flutter

I tried with different ways but i can't edit the structure of code
//First way
QuerySnapshot querySnapshot = await db.firestoreInstance.collection('user-history').get();
var list = querySnapshot.docs;
print('MY LIST ===== $list');
//Second way
final CollectionReference collectionRef = db.firestoreInstance
.collection(historyCollection);
print('MY SECOND LIST ===== $list');
collectionRef.get().then((qs) {
qs.docs.forEach((element) {
print('MY doc id ${element.id}');
});
});
In my firebase collection(historyCollection) i have four documents but the debugger returns me empty array []. Is there another way to call all documents in certain collection through flutter?
I'm trying to call this method through FutureBuilder component.
My version of firestore is: "cloud_firestore: ^0.16.0+1"
This should do the trick:
Future<List<dynamic>> getCollection(CollectionReference collection) async {
try {
QuerySnapshot snapshot = await collection.get();
List<dynamic> result = snapshot.docs.map((doc) => doc.data()).toList();
return result;
} catch (error) {
print(error);
return null;
}
}
The entire problem was not from these fragments of code. This problem is came out from this that my collections have subcollections. I read about this and i understand that subcollections can live without their ancestors and the only way to access parents is to do this is directly specify the exact path and name of the document. To work this code in my case was needed to add dummy components of my entire set of collections. For more information please look up these two topics:
-> https://firebase.google.com/docs/firestore/using-console
-> Firestore DB - documents shown in italics

Firebase | Problem with collectionGroup query

I'm trying to use a collectionGroup query to fetch the data from a specified farm, using firebase-functions. Here's my code:
app.get('/api/intervals/:farm_id', async (req, res) => {
const farmId = req.params.farm_id;
try {
const querySnapshot = await db
.collectionGroup('farms')
.where("id", "==", farmId)
.get();
const farmData = [];
querySnapshot.forEach((doc) => {
farmData.push(doc.data());
console.log(doc.id, ' => ', doc.data());
});
return res.status(200).send(farmData);
} catch (error) {
console.log(error);
return res.status(500).send(error);
}
});
There is definitely a farm in the database with the supplied code. For example, if I change the code in try to the below, I get the data as expected:
const farmRef = db
.collection('accounts')
.doc('lz8V32bjQGa9x1oecUu9')
.collection('farms')
.doc(farmId);
let farm = await farmRef.get();
let farmData = farm.data();
return res.status(200).send(farmData);
But I want to use a collectionGroup so I don't have to specify the parent account ID also.
What am I doing wrong here? Thanks in advance!
According to my understanding this is related with the fact that in your working code you are assigning directly from DocumentSnapshot, while in example in of the issue you are iterating over QuerySnapshot returned by get from query.
In documentation we can find that documents in QuerySnapshot are in array property docs.
So I think you should change forEach loop accordingly:
querySnapshot.docs.forEach((doc) => {
farmData.push(doc.data());
console.log(doc.id, ' => ', doc.data());
});
I have worked out that the problem was that my code was looking for a field named id. My query works if I manually add a field called ID as highlighted below: