I am trying to implement the function below but it gives me null.
To be specific, Future credit() is not updating the variable value. There is no problem with the database because if I put print(doc['value']) instead of value += doc['value'], I get the expected result.
It seems, getCredit() is the one returning null.
Future credit() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final String uid = user.uid;
int value = 0;
Firestore.instance
.collection('entries')
.where("uid", isEqualTo: uid)
.where("type", isEqualTo: "+")
.orderBy("time", descending: true)
.snapshots()
.listen((data) => data.documents.forEach((doc) => value += doc['value']));
print(value); // doesnt update value
return value;
}
int getCredit() {
credit().then((value) {print(value);});
credit().then((value) {return value;}); // return mot working
}
Thanks!
try this:
Future<int> getCredit() async {
return await credit();
}
Fixed it. It seems it was a problem with the scope of variable.
int cr = 0;
Future credit() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final String uid = user.uid;
Firestore.instance
.collection('entries')
.where("uid", isEqualTo: uid)
.where("type", isEqualTo: "+")
.orderBy("time", descending: true)
.snapshots()
.listen((data) => data.documents.forEach((doc) {cr = cr + doc['value'];}));
print('$cr');
}
Related
In the example below, I want to combine 2 firestore queries, but I could not get it to work.
final List<Who> pagedData =
await _query.get().then((QuerySnapshot snapshot) async {
if (snapshot.docs.isNotEmpty) {
_lastDocument = snapshot.docs.last;
} else {
_lastDocument = null;
}
return snapshot.docs.map((QueryDocumentSnapshot e) async {
final data = e.data() as Map<String, dynamic>;
Whoes w = Whoes.fromMap(e.data());
User u = await _firestore
.collection("user")
.doc(data['s'])
.get()
.then((DocumentSnapshot documentSnapshot) => User.fromMap(
documentSnapshot.data()));
return Who(w, u);
}).toList();
});
When I put await in the user part, things get confused and I couldn't edit it.
What I want to output as a result is List<Who>
What am I missing?
It gives me this error:
The return type 'List<Future<Who>>' isn't a 'Future<List<Who>>', as required by the closure's context.
I solved the problem, I leave it here for anyone who encounters this
final List<Who> pagedData =
await _query.get().then((QuerySnapshot snapshot) async {
if (snapshot.docs.isNotEmpty) {
_lastDocument = snapshot.docs.last;
} else {
_lastDocument = null;
}
Iterable<Future<Who>> futureWho =
snapshot.docs.map((QueryDocumentSnapshot e) async {
final data = e.data() as Map<String, dynamic>;
Whoes w = Whoes.fromMap(e.data());
User u = await _firestore
.collection("user")
.doc(data['s'])
.get()
.then((DocumentSnapshot documentSnapshot) => User.fromMap(
documentSnapshot.data()));
return Who(w, u);
});
Future<List<Who>> listWho = Future.wait(futureWho);
return listWho;
});
I am trying to get users name but Flutter gives this error:
The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.
Method:
String getUserNameFromUID(String uid) {
FirebaseFirestore.instance
.collection('users')
.where('uid', isEqualTo: uid)
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
return doc["name"];
});
});
}
How can I solve my problem? if I add return 0 to end of the method it always gives 0.
It always gives 0.(I do not want 0, I want get user name from uid)
String getUserNameFromUID(String uid) {
FirebaseFirestore.instance
.collection('users')
.where('uid', isEqualTo: uid)
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
return doc["name"];
});
});
return "0";
}
EDIT: I need a String solution, not Future. The method should return String...
Because my UI is not future builder. Isn't there any way to return one data as String in Firestore database?
First your function should return a Future<String> since it relies on firestore's get wich also returns a future. Also docs is a list, you have to return just one. The first one i guess. In the UI just use a FutureBuilder
Future<String> getUserNameFromUID(String uid) async {
final snapshot = await FirebaseFirestore.instance
.collection('users')
.where('uid', isEqualTo: uid)
.get();
return snapshot.docs.first['name'];
}
Since you can't use FutureBuilder. An ugly alternative is to pass a callback to getUserNameFromUID and call setState from there.
void getUserNameFromUID(String uid, Function (String name) onData) {
final snapshot = await FirebaseFirestore.instance
.collection('users')
.where('uid', isEqualTo: uid)
.get().then((s) => onData(s.docs.first['name']));
}
On your UI
...
getUserNameFromUID(uid, (String name){
setState(()=> name = name);
});
From your last comment just inherit from StatefulWidget. And call the function from inside.
#override
void initState() {
getUserNameFromUID(uid);
}
If you had special requirements about not being able to modify the UI, you should mention that as it conditions the way to use the backend services.
i have a problem with getting users, whose emails are in the other user's array 'SeniorList'. It prints me empty array when i have a user with an email from
_seniorList
I'm new to a Firebase so every advice is important.
Here is Firestore DB structure:
https://imgur.com/yrtJ4RZ
https://imgur.com/z3gurUq
And Code i tried:
Future<List<String>> getSeniorList() async {
var _currentUser = FirebaseAuth.instance.currentUser;
List<String> list;
DocumentSnapshot data = await FirebaseFirestore.instance
.collection('users')
.doc(_currentUser!.uid)
.get();
list = List.from(data['SeniorList']);
return list;
}
Future<void> printSeniorNameList() async {
final List<String> _seniorList = await getSeniorList();
print(_seniorList);
final QuerySnapshot result = await FirebaseFirestore.instance
.collection('users')
.where('email', arrayContainsAny: _seniorList)
.get();
final List<DocumentSnapshot> documents = result.docs;
print(documents);
}
PS. If u can tell me how to paste Images in a right way i will be thanksfull!
Solved it this way:
Future<List<String>> getSeniorList() async {
var _currentUser = FirebaseAuth.instance.currentUser;
List<String> list;
DocumentSnapshot data = await FirebaseFirestore.instance
.collection('users')
.doc(_currentUser!.uid)
.get();
list = List.from(data['SeniorList']);
return list;
}
Future<bool> isSeniorAlreadyInTheList(String checkemail) async {
final List<String> _seniorList = await getSeniorList();
if (_seniorList.contains(checkemail)) {
return true;
} else {
print('Email not in a Senior List');
return false;
}
}
Future<void> printSeniorNameWhoseEmailInTheList(String checkemail) async {
bool exists = await isSeniorAlreadyInTheList(checkemail);
Map<String, dynamic>? seniorName;
if (exists) {
var result = await FirebaseFirestore.instance
.collection('users')
.where('email', isEqualTo: checkemail)
.limit(1)
.get();
seniorName = result.docs[0].data();
print(seniorName!['username']);
} else
print('That users email is not in a SeniorList!');
}
Already Works for me.
how can I save all document Ids From firestore inside a list?
Thats what I tried but I couldn't manage to only save the ID:
List ticketIds = [];
getTicketIds() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
ticketIds = await FirebaseFirestore.instance
.collection("users")
.doc(prefs.getString("userId"))
.collection("tickets")
.get()
.then((val) => val.docs);
Hello you need to loop trough the docs and you can retreive the docs id, here is the code :
Future<List<String>> getTicketIds() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> ticketIds = await FirebaseFirestore.instance
.collection("users")
.doc(prefs.getString("userId"))
.collection("tickets")
.get()
.then((val) {
List<String> idOfDocuments = [];
val.docs.forEach((element) {
idOfDocuments.add(element.id);
});
return idOfDocuments;
});
return ticketIds;
}
I have added this collection:
Map<String, String> userDataMap = {
"userName": usernameEditingController.text,
"userEmail": emailEditingController.text,
"account": userType // there is premium and regular account type
};
...
Future<void> addUserInfo(userData) async {
Firestore.instance.collection("users").add(userData).catchError((e) {
print(e.toString());
});
}
And actually I don't know how to get info about account type, I would like to print/get value assigned to "account".
This is what I tried but it did nothing:
var ok = await Firestore.instance
.collection('users')
.where('email', isEqualTo: email)
.getDocuments();
print(ok);
Thank you in advance.
Inside the document, you have a field called userEmail and not email therefore you need to do the following:
var userDoc = await Firestore.instance
.collection('users')
.where('userEmail', isEqualTo: email)
.getDocuments();
userDoc.documents.forEach((result) {
print(result.data["account"]);
});