How to read Firestore field value in flutter? - flutter

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']}"),
};
}

Related

How to get particular data from List<Object> in flutter

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

Firebase Reference

How can I reference the collection in the document I auto-id in Firebase?
final CollectionReference _olanaklar5 = _database
.collection("Kategoriler")
.doc("Hoteller")
.collection("5_Yıldızlı")
.doc() //======> here
.collection("Olanaklar");
You can get list all document id with doc.id
List<String> _listDocId = [];
await fireStore
.collection("Kategoriler")
.doc("Hoteller")
.collection("5_Yıldızlı")
.get()
.then((QuerySnapshot querySnapshot) {
for (var doc in querySnapshot.docs) {
_listDocId.add(doc.id);
}
});
and query in list doc id
for (var id in _listDocId) {
final CollectionReference _olanaklar5 = _database
.collection("Kategoriler")
.doc("Hoteller")
.collection("5_Yıldızlı")
.doc(id)
.collection("Olanaklar");
}
If you're using Firebase auth, it's preferred to keep User's UID as doc, else you can use .where() as a query to match the fields in all documents. But as the app scales, it will be a hectic process and will consume many reads.

Flutter - Stream not returning data

I have a document collection called posts_favorites, which stores the reference to all the Posts that a user has bookmarked. The posts_favorites collection look as follows:
I have created a Stream to get all posts references that belong to a specific user, then I want to get the Post documents from the posts collection using the posts references.
I created a Stream to produce the data I need, but I am not getting any data returned from my Stream. Here is my code for the Stream:
Stream<List<PostsRecord>> getFavoritePostsStream() async* {
List<PostsRecord> myList = [];
await FirebaseFirestore.instance
.collection("posts_favorites")
.where("user", isEqualTo: currentUserReference)
.get()
.then((favoriteList) {
favoriteList.docs.forEach((element) async {
String documentPath = element['post'].toString();
var start = documentPath.indexOf("/");
var end = documentPath.indexOf(")");
var documentRef = documentPath.substring(start+1, end);
//DocumentReference docRef = FirebaseFirestore.instance.doc(documentPath);
DocumentReference docRef = FirebaseFirestore.instance.collection('posts').doc(documentRef);
await docRef.get().then((DocumentSnapshot documentSnapshot) async {
if (documentSnapshot.exists) {
print('Document exists on the database');
PostsRecord postsRecord = PostsRecord.getDocumentFromData(
documentSnapshot.data(), element['post']);
//return myList.add(postsRecord);
//print(postsRecord);
return postsRecord;
}
});
});
});
}
I know this function works because the commented code produces the Post Records that I expect to get from Firestore.
I am not sure how to get the Stream function to return data that I can use in the Stream.
Thank you

How to get a subcollection from a document firestore flutter

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;
}

Get value from one future and use it in another future, with Flutter

I have a favourites collection saved under a users collection. Each of the favourite documents has one field which contains a product_Id. I want to retrieve this product_id value and use it to query another collection. This second collection holds the actual products documents.
Retrieving all the documents in the favourite collection. What do I do next to get the value of the product_id fields as strings?
getIdsfromUserFavs(userId) async {
var _favData = await _usersCollectionReference
.doc(userId)
.collection('favourites')
.get();
}
This is the second method that is used to query the products collection. This method needs the String value from above in order to successfully make the query.
Future<QuerySnapshot<Object?>> queryFavsCollection(value) async {
var _favedProducts = await _productsCollectionReference
.where('prod_id', isEqualTo: value)
.get();
print(value);
return _favedProducts;
}
I am using a futureBuilder in the UI.
THis is one way I have tried(The problem with this is that I don't get any data returned):
getIdsfromUserFavs(userId) async {
var _favData = await _usersCollectionReference
.doc(userId)
.collection('favourites')
.get();
var allData = _favData.docs.map((doc) => doc.data()).toList();
allData.forEach((element) async {
String value = element['prod_id'];
print(value);
await queryFavsCollection(value);
});
}
Future<QuerySnapshot<Object?>> queryFavsCollection(value) async {
var _favedProducts = await _productsCollectionReference
.where('prod_id', isEqualTo: value)
.get();
print(value);
return _favedProducts;
}
I can see that the above methods print the ids to the console. But the FutureBuilder doesn't receive any data:
I/flutter ( 4628): 3nHHEWuCDXvbhYfT8ljY
I/flutter ( 4628): MptYFV1oXhflDYkdQyIP
I/flutter ( 4628): Fd2ntXyNVmjn0D6mG3RA
Below function will return all data from favourite collection
Future<QuerySnapshot<Map<String, dynamic>>> getIdsfromUserFavs(userId) async {
QuerySnapshot<Map<String, dynamic>> _favData = await _usersCollectionReference
.doc(userId)
.collection('favourites')
.get();
return _favData; // This will return all data of favourite collection
}
After that you can return List of desire data as shown in below function
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> queryFavsCollection(userId) async {
// Will store data in this list so at the end we can return this
List<QueryDocumentSnapshot<Map<String, dynamic>>> favData = [];
QuerySnapshot<Map<String, dynamic>> _favData =
await getIdsfromUserFavs(userId);
for (QueryDocumentSnapshot<Map<String, dynamic>> data in _favData.docs) {
String value = data['prod_id'];
QuerySnapshot<Map<String, dynamic>> _fav = await
_productsCollectionReference
.where('prod_id', isEqualTo: value)
.get();
if (_fav.docs.isNotEmpty) {
_fav.docs.forEach((element) {
favData.add(element);
});
}
}
return favData;
}
Now you can use FutureBuilder as shown below
FutureBuilder<List<QueryDocumentSnapshot<Map<String, dynamic>>>>(
future: queryFavsCollection(userId),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text('Loading...');
}
return Text('you data');
},
);
For better practice kindly refer this. This is from flutter documentation
"The future must have been obtained earlier, e.g. during State.initState, State.didUpdateWidget, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted."