I try to read all documents from collection as a model List from firestore like the java code.
Java code is
FirebaseFirestore.getInstance().collection("Product").addSnapshotListener((value, error) -> {
if (!value.isEmpty()){
List<Product> productList = value.toObjects(Product.class);
}
});
I try in flutter
QuerySnapshot data;
List<DocumentSnapshot> snapshot = new List<DocumentSnapshot>();
List<Product> productList = [];
data = await FirebaseFirestore.instance
.collection('Product')
.get();
snapshot.addAll(data.docs);
productList = snap.map((e) => Product.fromFirestore(e)).toList();
but always the list is empty, but the snapshot length is always same as my database.
database
Model class
void getProducts () async {
List<Product> productList = [];
var productsFromFirebase = await FirebaseFirestore.instance.collection("Product").get();
if (productsFromFirebase.docs.isNotEmpty) {
for (var doc in productsFromFirebase.docs) {
productList.add(Product.fromFirestore(doc)); //without '.data()' because you have it in your model.
}
}
print(productList.length); //prints the length of your products list.
}
Related
I am working on a chat app using Flutter and Firebase. I am new to Dart and so got stuck when I wanted to create a function which fetches (using await) a particular document from one collection (forums) and use an array property of the forum document to query and return a Stream from another collection (openMessages). The problem with my current solution is that it always returns an empty array. I am sure I am using the keywords or logic incorrectly. Can you please help me refactor my method.
Stream<List<ChatMessage>> getForumChatStream(String forumId) async* {
List<ChatMessage> messages = [];
var docSnap = await firestore.collection('forums').doc(forumId).get();
Forum forum = Forum.fromMap(docSnap.data()!);
firestore
.collection('openMessages')
.where('messageId', whereIn: forum.messageIds)
.orderBy('timeSent', descending: true)
.snapshots()
.map((event) {
for (var document in event.docs) {
messages.add(ChatMessage.fromMap(document.data()));
}
});
//print('LENGTH:'+messages.length.toString());
yield messages;}
You can use the following method.
Stream<List<ChatMessage>> getForumChatStream(String forumId) async* {
final firestore = FirebaseFirestore.instance;
List<ChatMessage> messages = [];
var docSnap = await firestore.collection('forums').doc(forumId).get();
Forum forum = Forum.fromMap(docSnap.data()!);
final result = firestore
.collection('openMessages')
.where('messageId', whereIn: forum.messageIds)
.orderBy('timeSent', descending: true)
.snapshots();
await for (final r in result) {
final docs = r.docs;
for (final document in docs) {
messages.add(ChatMessage.fromMap(document.data()));
yield messages;
}
}
}
Or
Stream<List<ChatMessage>> getForumChatStream(String forumId) async* {
final firestore = FirebaseFirestore.instance;
List<ChatMessage> messages = [];
var docSnap = await firestore.collection('forums').doc(forumId).get();
Forum forum = Forum.fromMap(docSnap.data()!);
yield* firestore
.collection('openMessages')
.where('messageId', whereIn: forum.messageIds)
.orderBy('timeSend', descending: true)
.snapshots()
.map((event) =>
event.docs.map((e) => ChatMessage.fromMap(e.data())).toList());
}
Im getting data using querysnapshot in my flutter project.
But can not print all the name from the List.
My code :
var collectionRef = FirebaseFirestore.instance.collection("users") .where("role",
isEqualTo: "Student");
Future<void> getData() async {
// Get docs from collection reference
QuerySnapshot querySnapshot = await collectionRef.get();
// Get data from docs and convert map to List
final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
print(allData.runtimeType);
for (var data in allData){
print(data['name']);
}
response from firebase
I want to get field value.
my code is..
void _checkNumner(String number) async {
final userRef = firestore.collection('users');
var documentSnapshot =
await userRef.where("number", isEqualTo: true).get().then((num) {
QuerySnapshot<Map<String, dynamic>> number = num;
print(number);
print("test");
});
print(documentSnapshot);
}
but my console is
how I get field number?
I want to load number values in all docs.
I'm so beginer. T.T
Please reply from the masters
Thank you
Firebase firestore is a NoSQL, document-oriented database. User Data is stored in documents which are organized into collection , i.e collection contains list of document. In simpler words we can say QuerySnapshot contains/provide group of DocumentSnapshot. more about firestore data model
Collection --> QuerySnapshot --> Group of DocumentSnapshot
Document --> DocumentSnapshot
1) Fetch from collection - QuerySnapshot
Here we'll get list of DocumentSnapshots, we can filter by using where commad
Future<void> checkNumber(int number) async {
final QuerySnapshot snapshot = await FirebaseFirestore.instance
.collection('users')
.where("number", isEqualTo: number)
.get();
snapshot.docs.isEmpty
? {
//TODO: your code here
debugPrint("no data found")
}
: {
for (DocumentSnapshot element in snapshot.docs)
{
//TODO: your code here
debugPrint("number is: ${element['number']}"),
debugPrint("name is: ${element['name']}"),
}
};
}
1) Fetch from document - DocumentSnapshot
To fetch data from document we require documentId, and we get a single documentSnapshot instead of multiple like in above way.
Future<void> checkNumberWithDocId() async {
const String docId = 'aaaa';
final DocumentSnapshot snapshot = await FirebaseFirestore.instance.collection('users').doc(docId).get();
snapshot.exists
? {
//TODO: your code here
debugPrint("no data found")
}
: {
//TODO: your code here
debugPrint("number is: ${snapshot['number']}"),
debugPrint("name is: ${snapshot['name']}"),
};
}
static List categoryList() {
final categorySnapshots = FirebaseFirestore.instance
.collection('categories')
.orderBy('name')
.snapshots();
List categories = [];
categorySnapshots.map((snapshot) => snapshot.docs.map((doc) {
print(snapshot.toString());
categories.add(doc.data()['name']);
}));
print(categories);
return categories;
}
Categories is empty.
How to populate it with the data from snapshots?
I added a new collection called "school", there're two items added inside the document.
void getMessagesTest() async{
QuerySnapshot querySnapshot = await _firestore.collection('school').orderBy('age',descending: true).get();
final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
print(allData);
}
I used my code, and it works. Could you please remove ".where" and try it again?
You could chain where and orderBy together. Please see my code below. Reference link => Using Where and Order by different fields in Firestore query
void getMessagesTest() async{
QuerySnapshot querySnapshot = await _firestore.collection('school').orderBy('age', descending: true).where('age', isGreaterThan: 17).get();
final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
print(allData);
}
Using the below code might help
you can convert the snapshot to Map<String,dynamic> by using the following function:
static Post fromSnap(DocumentSnapshot snap) {
var snapshot = snap.data() as Map<String, dynamic>;
}
Im trying to fetch the documents from a subcollection which is in another document, and when I try to fetch the docs and fill a local list with the "docs data" it doesn't fill it, can anyone tell me what I'm doing wrong here?
My method of when I try to fetch the subcollection:
static Stream<List<CheckInOutModel>> employeeCheckInOutStream() {
return firebaseFirestore
.collection('employees')
.doc(auth.currentUser!.uid)
.collection('employeeList')
.snapshots()
.asyncMap((QuerySnapshot querySnapshot) {
final List<CheckInOutModel> employeesCheckInOutList = [];
for (final element in querySnapshot.docs) {
firebaseFirestore
.collection('employees')
.doc(auth.currentUser!.uid)
.collection('employeeList')
.doc(element.id)
.collection('checkInOutList')
.snapshots()
.asyncMap((QuerySnapshot query) {
for (final element in query.docs) {
final employeeCheckInOutModel =
CheckInOutModel.fromDocumentSnapshot(
documentSnapshot: element,
);
employeesCheckInOutList.add(employeeCheckInOutModel);
}
});
}
return employeesCheckInOutList;
});
}
My method when I fetch the fields of the documents that the subcollection is in:
static Stream<List<EmployeeModel>> employeeStream() {
return firebaseFirestore
.collection('employees')
.doc(auth.currentUser!.uid)
.collection('employeeList')
.snapshots()
.map((QuerySnapshot query) {
final List<EmployeeModel> employees = [];
for (final employee in query.docs) {
final employeeModel =
EmployeeModel.fromDocumentSnapshot(documentSnapshot: employee);
employees.add(employeeModel);
}
return employees;
});
}
So I figured out what I did wrong here, I tried to call a stream of it when I only needed it when a callBack is called, so I changed the logic accordingly and went with Future instead Stream
My updated code:
static Future<List<CheckInOutModel>> employeeCheckInOutStream({
required String id,
}) async {
final List<CheckInOutModel> employeesCheckInOutList = [];
final query = await firebaseFirestore
.collection('employees')
.doc(auth.currentUser!.uid)
.collection('employeeList')
.doc(id)
.collection('checkInOutList')
.get();
for (final employee in query.docs) {
final employeeCheckInOutModel = CheckInOutModel.fromDocumentSnapshot(
documentSnapshot: employee,
);
employeesCheckInOutList.add(employeeCheckInOutModel);
}
return employeesCheckInOutList;
}