Saving document from Firestore database in Flutter - flutter

I am trying to get a document from the database where the users can put in an email and it will pull the document and save it so I can use the document in an editing module. Here is my readUsers method
Future ReadUserinDatabase(String email) async {
Stream<List<DatabaseUser>> User = FirebaseFirestore.instance
.collection('Users')
.where('Email' == email)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => DatabaseUser.fromJson(doc.data()))
.toList());
print(User.map);
}
I will be grabbing the document ID from the returned document so I can put it in for doc to edit
Future EditUserinDatabase(
String oldemail, String newemail, String oldrole, String newrole) async {
final docUser = FirebaseFirestore.instance.collection('TEST').doc('Doc ID goes Here');
await docUser.update({'Email': newemail, 'Role': newrole});
}
The error that is occurring is when I print User.map it is not printing the information in the document it is printing '$user' and is not saving in a form I can use it. How do I save the document

Related

How to calculate read/writes on Firestore operation?

I already know that having a direct path to a document id would result in a single read from the firestore through using the get() function. I am trying to retrieve a document fields value so I use FirebaseFirestore.instance.collection('users').doc(userUid).get() to get the documentSnapshot, then use await _userCollection.then((value) => value.get("field name")) to get the document field value. I do this to get "n" fields.
So, my question is would the second get() ,used to retrieve each document field, be calculated in the read costs or is it only the get() ,used to retrieve the documentSnapshot itself, which should be calculated.
Here is my full code:
_setStoreOwnerObjByFetchingUserData(String userUid) async {
Future<DocumentSnapshot<Map<String, dynamic>>> _userCollection =
FirebaseFirestore.instance.collection('users').doc(userUid).get();
await StoreOwner().updateOwnerData(
userUid,
await _userCollection.then((value) => value.get("shopName")),
await _userCollection.then((value) => value.get("shopAddress")),
await _userCollection.then((value) => value.get("shopType")),
await _userCollection.then((value) => value.get("shopSize")),
await _userCollection.then((value) => value.get("ownerName")),
await _userCollection.then((value) => value.get("ownerNumber")),
await _userCollection.then((value) => value.get("subscriptionStatus")));
}
Would the second get() ,used to retrieve each document field, be
calculated in the read costs or is it only the get() ,used to retrieve
the documentSnapshot itself, which should be calculated.
You only pay for the "get() used to retrieve the DocumentSnapshot". Once the asynchronous get() operation is complete the DocumentSnapshot is in memory in your app and you can call its get() method as many times as you want without any Firestore based cost.
THEREFORE it appears that in your code you query several times the database when it is not necessary. You should adapt it as follows:
_setStoreOwnerObjByFetchingUserData(String userUid) async {
Future<DocumentSnapshot<Map<String, dynamic>>> _userCollection =
FirebaseFirestore.instance.collection('users').doc(userUid).get();
var docSnapshot = await _userCollection;
await StoreOwner().updateOwnerData(
userUid,
docSnapshot.get("shopName"),
docSnapshot.get("shopAddress"),
//...
}

How to fetch document name from Firestore

Trying to fetch a document name "abcd".
await _firestore
.collection("users")
.where("name", isEqualTo: _auth.currentUser?.uid)
.get()
.then((value) {
setState(() {
userMap = value.docs[0].data();
});
});
.uid is not providing the document "abcd". How can I get it?
Only need the name of document.
That name "abcd" is the document id in your Firestore database, if you need to access it you will need to set the document id as its name which you look in the Firestore database :
await _firestore
.collection("users")
.doc("abcd")
.get() ; // this will get you the abcd document
and if you want to query your collection based on uid, and get the document information from it, first you will need a field called "name" which it's value id the user's uid, then :
await _firestore
.collection("users")
.where("name", isEqualTo: _auth.currentUser?.uid)
.get(querySnapshot).then(() {
final document = querySnapshot.docs.first;
print(document.id); // this will print abcd
});

How to merge a stream with another stream inside an await for loop - Flutter?

I have two streams coming from querying a firestore database instance like this:
Stream<Set<Place>> getUserPlaces(String userId, String listName) {
return _db
.collection('users')
.doc(userId)
.collection(listName)
.snapshots()
.map((snapshot) =>
snapshot.docs.map((doc) => Place.fromDB(doc.data())).toSet());
}
Stream<List<String>> getUserFriends(String userId) {
return _db
.collection('users')
.doc(userId)
.collection('friends')
.snapshots()
.map((snapshot) => snapshot.docs
.map(((doc) => doc.data()['friendUserId'].toString()))
.toList());
}
I have a separate Bloc class as an intermediary for my frontend UI and the backend firestore service.
class ApplicationBloc with ChangeNotifier {
final firestoreService = FirestoreService();
getAllPlace(String userId) async {
Stream<Set<Place>> userPlaces = firestoreService.getUserPlaces(userId, 'favorites');
Stream<List<String>> userFriends = firestoreService.getUserFriends(userId);
/*
Desired piece of code
*/
}
The firestoreService.getUserFriends(userId) function returns a stream of list of user ids which are strings. I want to use these returned user id strings to query my firestore db to return a set of 'Place' objects (which are a separate model not relevant to the question I think) using the firestoreService.getUserPlaces(userId, 'favorites') function.
Any ideas?
So far, I am stuck at this piece of code:
Stream<Set<Place>> userPlaces = firestoreService.getUserPlaces(userId, 'favorites');
await for (final place in userPlaces) {
/* Adding these 'place' variables to a list */
}
Stream<List<String>> userFriends = firestoreService.getUserFriends(userId);
await for (final friendUserIdList in userFriends) {
for (final friendUserId in friendUserIdList) {
Stream<Set<Place>> friendPlaces = firestoreService.getUserPlaces(friendUserId, 'favorites');
await for (final place in friendPlaces) {
/* Add these 'place' variables to the same list */
}
}
}
I am stuck because the code doesn't seem to execute the second 'await for' loop and is stuck listening to the first stream in the first 'await for' loop. I tried using the MergeStream API from RxDart to merge the first two streams but I feel the code will get stuck listening to a nested stream.

How to read Firestore field value in 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']}"),
};
}

How to update field using transaction?

My document contain array of objects as shown in image I'm trying to use transaction to update product_quantity as the user press add or minus button. How to access the usercart and update product_quantity field. The code that I have right now what it does is only to create new field with its value to this document
Future<void> updateCartQty(qty) {
DocumentReference documentReference = FirebaseFirestore.instance
.collection('Users')
.doc(_currentUser!.uid)
.collection("Cart")
.doc(_currentUser!.uid);
return FirebaseFirestore.instance
.runTransaction((transaction) async {
// Get the document
DocumentSnapshot snapshot = await transaction.get(documentReference);
if (!snapshot.exists) {
throw Exception("product does not exist!");
}
transaction.update(documentReference, {'product_quantity': qty});
return qty;
})
.then((value) => print("update cart"))
.catchError((error) => print("Failed to update product cart: $error"));
}