Flutter Firestore Query List Using WhereIn - flutter

I have a Firestore collection I am querying and referencing another document that I have already queried prior (teamRecord). In this case everything is working up to the final 'user_inchallenge' call. In this case, the user_inchallenge is a DocumentReference and the teamRecord.usersInTeam is a List of DocumentReferences. However, there whereIn call does not seem to be working properly. I only want to return docs where user_inchallenge is held within teamRecord.usersInTeam.
FirebaseFirestore
.instance
.collection('activity_units')
.orderBy('activity_value', descending: true)
.where('challenge_reference', isEqualTo: challenges.reference)
//below is not working
.where('user_inchallenge', whereIn: teamRecord.usersInTeam.asList())
As a note, if I remove the .asList() call in usersInTeam I get the error:
The argument type 'BuiltList<DocumentReference>' can't be assigned to the parameter type 'List'.
I also tried isEqualTo, arrayContains, but none of them have returns the filtered results.

The whereIn parameter expects a List, and it seems that BuiltList is not actually a List.
You'll want to convert your BuiltList to a List (e.g. by calling asList() or toList() on it) and then pass that to the Firestore call.
I filed issue #10407 on the GitHub repo to see if the types can be change to be Iterable.

Related

Flutter Firebase where clause mixing between isNotEqualTo and isEqualTo clauses causes data to not showed up

I'm still learning about Flutter with firebase.
So, I want to make a to-do-list (TDL) app, that can shows TDL item in the home page.
TDL can have 1 of these 3 status (selesai [finished], belum [not yet], telat [late]),
and i wanted to show the ones which status is belum and telat, or simply the ones which status is not equal to selesai, and has the idProject equal to "0".
Simply i need to show TDL which has idProject = "0" and status!="selesai".
So i wrote this:
static Stream<QuerySnapshot> getDataTDL() {
return CToDoList
.where("status",isNotEqualTo:"selesai")
.where("idProject",isEqualTo: "0")
.snapshots();
}
here's a quick look on my data at firebase.. So, basically it should at least return this one -actually there's few more datas it can return- because it matched my where-clause requirements, but in fact it returns nothing at all.
So what can i do now?
As your query contains both a not equal and an is equal comparison, you will have to create a composite index for the query. If you check the error logs of the flutter process, Firestore should give you a link you could use to create the index. If you can't find the link you would have to manually create it in the Firebase console for the project. More info is here.

Flutter get future list data into normal list

I am trying to show a list of items in a DropdownField, which requires a non-future list.
So I am trying to turn my future list (which I get from a database call) into a normal list by iterating over it and adding it to a new, normal, list, like so;
When I print the individual elements of the future list, I get results back.
But afterwards, when I print the new list, it returns as a null value.
Does anyone have any idea as to how I can solve this issue ?
PS: I am NOT interested in a FutureBuilder solution. I know that I can show a future list with a futurebuilder, but this will not fit the solution I am hoping to achieve.
Thanks in advance!
That’s because you’re not waiting for the future to complete. When you do print(newList) the future isn’t completed yet.
You will have to need to await the getAnswers data to archieve what you want.
final answers = await getAnswersList();
for (final answer in answers) {
print(answer.toString());
}
The problem is that you are not initializing newList. You are trying to add items to a null list. Change the fourth line of getAll() to the following:
var newList = List<dynamic>();
You are also not awaiting your firebase call. This means that you will print the array BEFORE you finish your firebase call. You need to make this getAll() method async and await, the firebase call so it doesn't print the null version.

How do you remove a nested dictionary(map) from Firestore?

I'm trying to make a method that removes a nested dictionary from my firebase database. The documentation says to use FieldValue.delete() but that only works for dictionaries on the first level. Setting the key equal to nil doesn't work either; this changes its value to "null" in firebase, but doesn't delete it.
database
.collection("users")
.document(userID)
.updateData([
"dict1":[
"dict2":***thisIsTheValueINeedToDelete***
]
])
FieldValue.delete() works for nested maps as well. You will need to use the dot notation to call out the full path of the nested map.
.updateData(["dict1.dict2": FieldValue.delete()])

CRUD flutter/firestore/firebase

I am new to coding and what I am trying to achieve is to set up a method that checks the 'MONDAY' collection inside post and if the data exist? the values of the fields get updated otherwise they get created! I have been stuck for a while now and been redirected to different solutions but nothing has worked for me. I appreciate all help
Future<void> createPostMonday(Post post) async{
await postsRef.document(post.authorId).collection('Monday').setData({
'alOne':post.alOne,
'alTwo':post.alTwo,
'alThree':post.alThree,
'alFour':post.alFour,
'alFive':post.alFive,
'alSix':post.alSix,
'beOne':post.beOne,
'beTwo':post.beTwo,
'beThree':post.beThree,
'beFour':post.beFour,
'beFive':post.beFive,
'beSix':post.beSix,
'likes': post.likes,
'authorId': post.authorId,
'timestamp': post.timestamp,
});
setData() is used to write the contents of a single document whose ID you already know. It requires that you use a DocumentReference object to locate that document.
If you're trying to add a new document to a collection with a unique random ID, you should use add() method of a CollectionReference.
await postsRef.document(post.authorId).collection('Monday').add(...)

Flutter Firestore getting incomplete array

I'm trying to fetch an array of strings I have saved on my database but I'm getting the array back with missing values, only the first value is shown inside of it. Here's the structure of my database:
Path: /users/uid/services <-- this is the array
Path: /services/uid <--service document
The code I'm using to retrieve the users is:
_getWorkers() async {
var query = await Firestore.instance.collection('users').where('services', arrayContains: widget.category['uid']).getDocuments();
query.documents.forEach((doc) {
workers.add(doc.data);
List<String> values = List.from(doc.data['services']);
print('services:' + values.toString());
});
var test = await Firestore.instance.collection('users').document('PtBD2EMSTodvlx6WHUx8QOHHLNA2').get();
print('actual services:' + test['services'].toString());
}
Both query and test get data back, but the services array only contains the first value.
Its difficult to answer without actually seeing the entire DB structure. But still on the outset i can see only one error with your code.
When you are trying to execute the where() call, try adding the snapshots to retrieve all relevant data.
Since await is also used, it is much better to call the listen() on it and then read the values to be added to the worker
Try using this below code in place of your first line.
await Firestore.instance.collection('users').where('services', arrayContains: widget.category['uid']).snapshots().listen((query)=>query.documents.forEach((doc)=>print(doc.data['services'])));
For some reason Firebase wasn't returning the updated array. Tested it again today and it worked with the same code. Sorry for bothering, thanks for the help anyways.