Flutter Populating List<String> using for loop - flutter

I want to get all the document IDs in my firebase and store it in List but I'm only getting one of the documents. Here is my execution
PrtSc
my code
Future saveUserCart(User currentUser) async
{
List<String> IDs = [];
Future getDocs() async {
QuerySnapshot querySnapshot = await FirebaseFirestore.instance
.collection('users')
.doc(currentUser.uid)
.collection("userCart").get();
for (int i = 0; i < querySnapshot.docs.length; i++) {
var itemIDs = querySnapshot.docs[i];
print(itemIDs.id);
IDs = [itemIDs.id];
}
print(IDs);
}
getDocs();
}
Fix my problem and learn something

Try IDs.add(itemIDs.id); instead of IDs=[itemIDs.id];

Instead of adding the code in question is creating a new list and assigning it to the last id. When we use add method we can get all ids from the documents.
Future saveUserCart(User currentUser) async
{
List<String> IDs = [];
Future getDocs() async {
QuerySnapshot querySnapshot = await FirebaseFirestore.instance
.collection('users')
.doc(currentUser.uid)
.collection("userCart").get();
for (int i = 0; i < querySnapshot.docs.length; i++) {
var itemIDs = querySnapshot.docs[i];
print(itemIDs.id);
IDs.add(itemIDs.id);
}
print(IDs);
}
getDocs();
}

It's just Example,
you can use base on your requirements. For gettings "ID" you don't need to use for loop, use "map" functions.
var data = [{'key':'abc', 'id':1},{ 'key': 'xyz', 'id': 2}];
var mapData = data.map((res) => res['id']);
print("mapData => ${mapData.toList()}");
Expected Output,
mapData => [1, 2]
Maybe, it will help you.

Related

How can i manually add document-fields into local QueryDocumentSnapshot List

i have the following list
List <QueryDocumentSnapshot> globalVideosUrls = [] ;
for example if we use the following
FirebaseFirestore.instance.collection('users')
.limit(1).get().then((value){
globalVideosUrls.add(value)
});
it will add as expected
but what if i want to manually add the following data into globalVideosUrls
document id
00dcb026-3163-4ca0-859e
fields
'videoType':'peace'
'url':'url'
.
globalVideosUrls.add(????)
You have to replace the type "QueryDocumentSnapshot" with QuerySnapshot and then you will get multiple docs and with there data also try this If any questions then ask.
thanks🙏.
List<QuerySnapshot> globalVideosUrls = [];
List<String> videoUrlList = [];
await FirebaseFirestore.instance
.collection('users')
.get()
.then((value) {
globalVideosUrls.add(value);
});
globalVideosUrls.forEach((element) {
element.docs.forEach((docELe) {
print("data:- ${docELe.data()}");
Map map = docELe.data() as Map;
videoUrlList.add(map['url']);
});
});

How do I ensure that the list is populated before checking what it contains?

In the code snippet below, how do I ensure that the senderID list gets populated before checking what the list contains?
I'm pulling data from firestore, storing it in a list, and then checking if it contains a particular key.
Stream<List<Group>> getChatGroups(String grpId) {
return firestore.collection('groups').snapshots().map((event) {
List<Group> groups = [];
List<String> senderIds = [];
for (var document in event.docs) {
var group = Group.fromMap(document.data());
firestore.collection('groups').doc(group.groupId).collection('chats').get().then((QuerySnapshot snapshot) {
snapshot.docs.forEach((DocumentSnapshot doc) {
var messageData = doc.data() as Map<String, dynamic>;
var messages = Message.fromMap(messageData);
var grId = doc.reference.parent.parent?.id;
//The values in SenderIds should be set before the function below is initiaited
senderIds.add(messages.senderId);
});
});
//This if function should initiate after getting set above
if (senderIds.contains(auth.currentUser!.uid)) {
groups.add(group);
}
}
return groups;
});
}
If you want senderIds.contains to be called only after all of your Futures have completed, build a List of those Futures and use Future.wait on that List. Something like:
var futures = <Future<void>>[];
for (var document in event.docs) {
// ...
futures.add(
firestore
.collection('groups')
.doc(group.groupId)
.collection('chats')
.get()
.then((QuerySnapshot snapshot) {
// ...
}),
);
}
await Future.wait(futures);
if (senderIds.contains(auth.currentUser!.uid)) {
// ...
}
Note that since the above code is asynchronous, you should also be using asyncMap instead of map.

async function not completing when querying FirebaseFirestore

See the print statement down below. It never executes.
Future<void> populate() async {
final userId = FirebaseAuth.instance.currentUser!.uid;
final db = FirebaseFirestore.instance;
// Get list of ids of parties use swiped on.
var snapshot1 = await db
.collection("partiers_swipes")
.where('userId', isEqualTo: userId)
.get();
var partyIdsUserSwipesOn = [];
if (snapshot1.size > 0) {
snapshot1.docs.forEach((element) {
partyIdsUserSwipesOn.add(element.data()['partyId']);
});
}
var snapshot2 = await db
.collection("parties")
.where(FieldPath.documentId, whereNotIn: partyIdsUserSwipesOn)
.get();
print('This never executes');
}
The whereNotIn argument is not supported by the where clause. This crashes the function.

How to use firestore as an input for my tflite model in flutter?

I've been playing with mobile apps and firestore recently and wanted to put a simple predictive model inside my app. I did put it but i want to get data from my firestore to use it as input for my predictive model. The shape of my inputdim is 5 that is why i used the limit function of firestore to get 5 values but instead of values im getting the whole document content instead of the value of the field "amount"
List mlinpt = [];
final CollectionReference mlPut = FirebaseFirestore.instance
.collection('UserAccounts')
.doc(myUid)
.collection('dataInference');
getUserInputList() async {
await mlPut.orderBy('amount', descending: true).limit(5).get().then((querysnapshot) {
for (var result in querysnapshot.docs) {
mlinpt.add(result.data());
}
});
}
Future<void> predData() async {
final interpreter = await Interpreter.fromAsset('model/kerasregopt.tflite');
var input = [mlinpt];
var output = List.filled(1, 0).reshape([1, 1]);
interpreter.run(input, output);
print(output[0][0]);
this.setState(() {
predValue = output[0][0].toString();
});
}
List mlinpt = [];
final CollectionReference mlPut = FirebaseFirestore.instance
.collection('UserAccounts')
.doc(myUid)
.collection('dataInference');
getUserInputList() async {
await mlPut.orderBy('amount', descending: true).limit(5).get().then((querysnapshot) {
for (var result in querysnapshot.docs) {
mlinpt.add(result.data());
}
});
}
Future<void> predData() async {
final interpreter = await Interpreter.fromAsset('model/kerasregopt.tflite');
var input = [mlinpt];
var output = List.filled(1, 0).reshape([1, 1]);
interpreter.run(input, output);
print(output[0][0]);
this.setState(() {
predValue = output[0][0].toString();
});
}
I tried getting the snapshot of the values i want in firestore but i think i dont quite understand how it works or how i should use it

getting documents from another collection problem can't solve

i have these 2 collection with a users collection and i want to make a list of providers for one user
i tried this code but not give me results :(
Future<List<ServineraProvider>> getfavoritesForUser() async{
List<ServineraProvider> providers = [];
await providerSkillsCollection.where('providerID', isEqualTo: this.uid).get()
.then((onValue){
for(int i=0; i<onValue.docs.length; i++){
var doc = onValue.docs[i].data() as Map<String,dynamic>;
print(doc['skillID']);
skillsCollection.doc(doc['skillID']).get()
.then((doc){
var data = doc.data() as Map<String,dynamic>;
providers.add(ServineraProvider(
providerID: data['providerID'],
providerName: data['providerName'],
providerEmail: data['providerEmail'],
providerPhoneNumber: data['providerPhoneNumber'],
providerPicture: data['providerPicture'],
providerState: data['providerState'],
providerStatus: data['providerStatus']
)
);
});
}
});
return providers;
}
i know there is a mistake but can't solve
You're combining then with await, which is almost never a good idea. In this case it results in returning the providers list after the providerSkillsCollection query has completed, but before any of the providers themselves have been loaded.
To solve the problem with just await:
Future<List<ServineraProvider>> getfavoritesForUser() async{
List<ServineraProvider> providers = [];
var onValue = await providerSkillsCollection.where('providerID', isEqualTo: this.uid).get()
for(int i=0; i<onValue.docs.length; i++){
var doc = onValue.docs[i].data() as Map<String,dynamic>;
print(doc['skillID']);
var doc = await skillsCollection.doc(doc['skillID']).get()
var data = doc.data() as Map<String,dynamic>;
providers.add(ServineraProvider(
providerID: data['providerID'],
providerName: data['providerName'],
providerEmail: data['providerEmail'],
providerPhoneNumber: data['providerPhoneNumber'],
providerPicture: data['providerPicture'],
providerState: data['providerState'],
providerStatus: data['providerStatus']
));
}
return providers;
}