Query a document value in a nested collection in firebase - firebase

I need to get the values from a document with this schema in Firebase:
COLLECTION => DOCUMENT => COLLECTION => DOCUMENT
userPolls => userId => dailyPolls => 20200825 => pollDate: "2020/08/25"
status: "Under PUM"
statusCode: "pum"
uid: "zwQnrrBdNCemWyXEW2LHmw8LejA2"
This is my attempt at it. But I think I am getting it wrong in flutter
final CollectionReference userPollCollection =
Firestore.instance.collection('userPolls');
Future getPoll() async {
final DateTime now = DateTime.now();
final DateFormat formatter = DateFormat('yyyy/MM/dd');
final String formatted = formatter.format(now);
var pollDate = formatted;
var docRef = await applicationUser
.document(userId)
.collection('dailyPolls')
.document(pollDate);
docRef.get().then((onValue) => {print(onValue.data['status'])});
}
I know that this is not right. Can you please show me how? Thank you.
EDIT
For reference, this is how I ADD data to the firestore db:
Future setPoll(UserPoll userPoll) async {
var dt = userPoll.pollDate.replaceAll('/', '');
return await userPollCollection
.document(userId)
.collection('daillyPolls')
.document(dt)
.setData({
'uid': userId,
'pollDate': userPoll.pollDate,
'status': userPoll.status,
'statusCode': userPoll.statusCode
});
}
This is how I try to get it
Future getPoll() async {
final DateTime now = DateTime.now();
final DateFormat formatter = DateFormat('yyyy/MM/dd');
final String formatted = formatter.format(now);
var pollDate = formatted;
var dt = pollDate.replaceAll('/', '');
var docRef = userPollCollection
.document(userId)
.collection('dailyPolls')
.document(dt);
docRef.get().then((onValue) {
print(onValue.data);
});
}
}
If I use this code based on the help of Peter Haddad, I get a null value when printing my result.data

You have to do the following:
var docRef = Firestore.instance.collection("userPolls").document(userId).collection('dailyPolls').where("pollDate", isEqualTo: pollDate);
var result = await docRef.getDocuments();
result.documents.forEach((result) {
print(result.data);
});
});
Since pollDate is an attribute inside a document then you can use the where() method to query and get the document

Related

How to read read a value from firebase document field

here is the firebase firestore section
how do I read the value 'purchase-id'
this is how I did, but not working
var collection = FirebaseFirestore.instance.collection('users');
final docSnapshot = await collection.doc('$index').get();
Map<String, dynamic> data = docSnapshot.data()!;
final purID = data['purchased-id'];
the value is receiving but as the future value
here is how the value is receiving
final purchaseID = coursePurchaseCheck
but this is a Future value, how do I parse that to normal data
how do I properly get document value from firebase??
Check your index is equal to document key ??
You can get document key with below code:
List<String> _userKey = [];
await fireStore
.collection('user').get()
.then((QuerySnapshot querySnapshot) {
for (var doc in querySnapshot.docs) {
_userKey.add(doc.id);
}
});
And get data below:
for(String _key in _userKey){
await FirebaseFirestore.instance
.collection('user')
.doc(_key)
.get()
.then((DocumentSnapshot documentSnapshot) async {
if (documentSnapshot.exists) {
var data = documentSnapshot.data();
var res = data as Map<String, dynamic>;
final purID = res['purchased-id'];
}
});
}

flutter FirebaseStorage onComplete

void validateAndUpload() async {
if (_formKey.currentState.validate()) {
setState(() => isLoading = true);
if (_image1 != null) {
if (selectedSizes.isNotEmpty) {
String imageUrl1;
final FirebaseStorage storage = FirebaseStorage.instance;
final String picture1 =
"${DateTime.now().millisecondsSinceEpoch.toString()}.jpg";
StorageUploadTask task1 =
storage.ref().child(picture1).putFile(_image1);
task1.onComplete.then((snapshot1) async {
imageUrl1 = await snapshot1.ref.getDownloadURL();
_productServices.uploadProduct(
productName: productNameController.text,
brandName: _currentBrand,
details: detailController.text,
category: _currentCategory,
quantity: int.parse(quantityController.text),
size: selectedSizes,
picture: imageUrl1,
feature: feature,
sale: sale,
price: double.parse(priceController.text));
_formKey.currentState.reset();
The getter 'onComplete' isn't defined for the type 'UploadTask'. (Documentation) Try importing the library that defines 'onComplete', correcting the name to the name of an existing getter, or defining a getter or field named 'onComplete'.
That error seems correct. Did you mean whenComplete?
I typically prefer to simply await the task though:
var ref = storage.ref().child(picture1);
await ref.putFile(_image1);
imageUrl1 = await ref.getDownloadURL();
...
final ref = FirebaseStorage.instance
.ref("${DateTime.now().millisecondsSinceEpoch.toString()}.jpg");
var uploadEvent = ref.putFile(_image1!);
String imageUrl = await (await uploadEvent.whenComplete(() => null))
.ref
.getDownloadURL();

Pass variable from function to late stream flutter

I am trying to get getGrupoFav to pass it as a variable to the late Stream<QuerySnapshot> task..., I tried with get but I did not know how to do it and I did not find a solution, I do not know if there is a better way to do it.
the error says
"Try correcting the name to the name of an existing getter, or defining a getter or field named 'getGrupoFav'.
.doc(getGrupoFav)
"
_fetch() async {
final String? userID = FirebaseAuth.instance.currentUser?.uid;
await FirebaseFirestore.instance
.collection("usuarios")
.doc("$userID")
.get()
.then((value) {
String getGrupoFav = value.data()!["grupofav"];
return getGrupoFav;
}).catchError((e) {
print(e);
});
}
late Stream<QuerySnapshot> task = FirebaseFirestore.instance
.collection("grupos")
.doc(getGrupoFav)
.collection("tareas")
.snapshots();
You should build your code something around like below and for the Flutter code syntax please have a look at this documentation
var collection = FirebaseFirestore.instance.collection('usarios');
var userID = FirebaseAuth.instance.currentUser?.uid;
var docSnapshot = await collection.doc(userID).get();
if (docSnapshot.exists) {
Map<String, dynamic> data = docSnapshot.data()!;
var name = data['name'];
}
Then you pass this variable to the document like,
var task = FirebaseFirestore.instance .collection("grupos") .doc(name).snapshots()

How do you create a dynamic filter on List based on firebase string?

I am trying to include a dynamic filter using string from firestore. The UI will show tiles based on a selection on filter(s)
I have have query to fetch Firebase documents below
getFoods(FoodNotifier foodNotifier) async {
QuerySnapshot snapshot = await Firestore.instance
.collection('Foods')
.orderBy('create at', descending: true)
.getDocuments();
List<Food> _foodList = [];
Here below these are the string I have setup in firestore.
import 'package:cloud_firestore/cloud_firestore.dart';
class Food {
String id;
String name;
String category;
String newcategory;
String image;
List subIngredients = [];
Timestamp createdAt;
Timestamp updatedAt;
static var data;
Food();
Food.fromMap(Map<String, dynamic> data) {
id = data['id'];
name = data['name'];
category = data['category'];
newcategory = data['newcategory'];
image = data['image'];
subIngredients = data['subIngredients'];
createdAt = data['create at'];
updatedAt = data['updatedAt'];
}
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'category': category,
'newcategory': newcategory,
'image': image,
'subIngredients': subIngredients,
'create at': createdAt,
'updatedAt': updatedAt,
};
}
If I understand you correctly, you are trying to build a query out of multiple conditions. Every time you call where it returns a new Query object. So by calling that for each condition, you can build up the query.
var query = Firestore.instance
.collection('Foods')
.orderBy('create at', descending: true);
if (food.category != "") {
query = query.where("category", isEqualTo: food.category);
}
if (food.name != "") {
query = query.where("name", isEqualTo: food.name);
}
QuerySnapshot snapshot = await query.getDocuments();
...

How to build a Map<DateTime, List> from firebase data in flutter

i am trying to create a map as Map from firebase.
I tried this
Future<Map<DateTime, List>> getlist() async {
QuerySnapshot querySnapshot = await Firestore.instance
.collection("${_username.toLowerCase()}-orders")
.getDocuments();
var list = new List.generate(querySnapshot.documents.length, (int index) => querySnapshot.documents[index]['date']);
var datelist = list.toSet().toList();
var map = new Map.fromIterable(datelist,
key: (item) => DateTime.parse(item),
value: (item) => () async {
QuerySnapshot querySnapshot2 = await Firestore.instance
.collection("${_username.toLowerCase()}-orders")
.where('date', isEqualTo: item)
.getDocuments();
var ordlist = new List.generate(querySnapshot2.documents.length, (int index) => querySnapshot2.documents[index]['name']);
return ordlist;
});
print(map);
return map;
}
I get an error like this
The return type 'Map<DateTime, () → Future<List<dynamic>>>' isn't a 'Future<Map<DateTime, List>>', as defined by the method 'getlist'.dart(return_of_invalid_type)
Help me
In your value: argument you have a typo. What you wrote is (item) => () async {...} when you likely meant (item) async {...}. What you wrote is an arrow function, that returns a function.
Even after that what you'll have is a Map<Datetime, Future<List<dynamic>> and you'd need to resolve all those Future to get a Map<DateTime, List<dynamic>>. I note that you're doing a new query for each date, but I think you should already have those values available after the first query...
It looks like groupBy from package:collection would get you pretty close, you'd still need one more .map call to extract the 'name' field...
Future<Map<DateTime, List>> getlist() async {
var querySnapshot = await Firestore.instance
.collection("${_username.toLowerCase()}-orders")
.getDocuments();
var items = querySnapshot.documents;
var grouped = groupBy(items, (item) => item['date']);
var map =
grouped.map((date, item) => MapEntry(DateTime.parse(date), item['name']));
print(map);
return map;
}

Resources