Flutter if statement not functioning - flutter

This should be an easy one but I've been stuck for hours.
Situation: I'm trying to execute the signOutProcess to log out of Firebase if the user is not authorized. I've set up a field in Firestore, 1 for authorized and 0 for not authorized. It prints the correct result, I can get it to sign out if I remove the if statement but that defeats the purpose.
Question: How do I get the if statement to execute signOutProcess when the nested value is retrieved?
void getUserAuthorization () {
String uid = firebaseAuth.currentUser!.uid;
print('this is uid $uid');
FirebaseFirestore.instance
.collection('Users2022')
.doc(uid)
.get()
.then((DocumentSnapshot documentSnapshot) async {
dynamic nested = documentSnapshot.get(FieldPath(['Authorized']));
print('this is the authorization condition $nested');
if (nested == 0) {
signOutProcess();
}
});
}

Likely the value you get is '0' and not 0, i.e. it's a string!
It won't be equal to the number 0 then, and instead you'd have to write if (nested == '0').
You can try print(nested.runtimeType) to see what you actually got there.

Related

Handling Multiple Optional Conditions in Firestore Queries - flutter

I want to get documents from Firestore with conditions. There are 5 conditions where 4 of them are optional. It depends on user input (the user can enter conditions. depending on the user.)
My problem is that I have to create indexes in Firestore. If I use 5 conditions all time, It's enough 1 index. But, In this situation, Some users use 4 conditions, and someone uses 2,3,1. I don't know how many. So, I have to create many indexes. (more than 20). What can I do about this?
I have an idea for it.
All conditions work every time (1 index), But, If the user does not give value to that condition, That condition give all documents. So, I used this method to success my idea. But there is errors. help me to improve my idea or give me another idea to do this.
Code for my idea:
set a function to Stream of StreamBuilder Widget.
That function's code below:
profession, religion, status etc. values get from user inputs.
Stream<QuerySnapshot> getDataStream(
String religion,
String status,
String profession,
String foods,
String education,
) {
var query = FirebaseFirestore.instance
.collection("users")
.where("ethanicity", isEqualTo: "Test");
// religion
if (religion != "") {
query = query.where("religion", isEqualTo: religion);
}
if (religion == "") {
query = query.where("religion", isNotEqualTo: "");
}
// Status
if (status != "") {
query = query.where("status", isEqualTo: status);
}
if (status == "") {
query = query.where("status", isNotEqualTo: "");
}
// // profession
if (profession != "") {
query = query.where("profession", isEqualTo: profession);
}
if (profession == "") {
query = query.where("profession", isNotEqualTo: "");
}
// // foods
if (foods != "") {
query = query.where("status", isEqualTo: foods);
}
if (foods == "") {
query = query.where("status", isNotEqualTo: "");
}
//education
if (education != "") {
query = query.where("education", isEqualTo: education);
} else {
query = query.where("education", isNotEqualTo: "");
}
return query.snapshots();
}
Problem :
I can use isNotEqualTo multiple times in a single query. Can't use like this.
I know two ways to do this, the scalable and the not so scalable version.
Scalable: Use Algolia plugin as an external service to search, it's worth the time learning as you will have a bunch of power for queries.
The other solution is as per https://firebase.google.com/docs/firestore/query-data/queries#limitations firebase limitation, you can only filter on the same field.
You could create an array field called filters ["status", "religion"] and from there you can use a where in query. Now, this is hard to escalate as you would have to update such an array every time a property changes.

flutter firestore: how to get a query of documents

Im trying to get a list of user objects from firestore through a query. My current attempt looks like this:
List<User> getDiscoveryUsers(
String userId,
) async {
Query<Object?> query =
userCollection.where('finishedOnboarding', isEqualTo: true).limit(10);
var collection = await query.get();
//get the users list from query snapshot
var users = collection.docs.map((doc) => User.fromSnapshot(doc)).toList();
return users;
}
However I am getting the error:
Functions marked 'async' must have a return type assignable to 'Future'.
Try fixing the return type of the function, or removing the modifier 'async' from the function body.
I know there are a few similar questions on stack overflow, but i just cant seem to get this to work. Anyone know whats going on?
Thanks!
Just change the return type of your function from List<User> to Future<List<User>>.
Happy coding:)
your return type should be Future and must wait with await when running query on firestore.
Future<List<User>> getDiscoveryUsers(
String userId,
) async {
Query<Object?> query =
userCollection.where('finishedOnboarding', isEqualTo: true).limit(10);
var collection = await query.get();
//get the users list from query snapshot
var users = collection.docs.map((doc) => User.fromSnapshot(doc)).toList();
return users;
}

How to correctly fetch data from firebase using where clauses and custom filters from firebase using flutter

Im trying to fetch data using
Stream<List<User>> getUsers(User user) {
return _firebaseFirestore
.collection('users')
// .where('interestedIn', isEqualTo: _selectInterest(user))
.snapshots()
.map((snap) {
return snap.docs.map((doc) => User.fromSnapshot(doc)).toList();
});
}
The filter used in the where clause is as follows
_selectInterest(User user) {
if (user.interestPreference == null) {
return ['HIRING', 'WORK'];
}
return user.interestPreference;
}
In firebase I store interestPreference as an Array with 'HIRING' as the only element in the current user's data, when I try to fetch users with 'HIRING' in their interestedIn which is a string I dont get any data. But when I hardcode the where clause as
.where('interestedIn', isEqualTo: 'HIRING')
I get the data, Can anyone help me solve my dilemma?
From that last query, it sounds like the interestedIn field in your database is a single string value, like interestedIn: "HIRING".
Your current query returns documents where interestedIn is an array with exactly the two values you specify, so interestedIn: ['HIRING', 'WORK']
If you want to return all documents where interested in is either "HIRING" or "WORK", you can use an IN condition:
.where('interestedIn', whereIn: ['HIRING', 'WORK'])
Or with your helper function:
.where('interestedIn', whereIn: _selectInterest(user))

Flutter firestore returns length 0 while there is data in firestore

I have the following code in flutter:
QuerySnapshot querySnapshot =
await _firestore.collection("user1#gmail.com").get();
List Data = querySnapshot.docs.map((doc) => doc.data()).toList();
print("Length: ${Data.length}");
Here is my firestore database:
I get the following output:
I/flutter (11484): Length: 0
The Documents for each user email is variable, so I need the length of the documents. Also I need to get to the details of each document like content and title. How to do it? Thanks.
Could you try this:
int size = await FirebaseFirestore.instance.collection(collectionPath).get(GetOptions(source:Source.server))..size;
I will recommend finding a way to store the length of documents as a field in your Cloud Firestore database because calling the get function on a whole collection means filling up the mobile phone memory. (Say you have 500,000 users at least). This makes your app slow
You could have a field called count such that when you add a document, you can use the firebase transaction to update firebase.
For example:
// Create a reference to the document the transaction will use
DocumentReference documentReference = FirebaseFirestore.instance
.collection('users')
.doc(documentId);
return FirebaseFirestore.instance.runTransaction((transaction) async {
// Get the document
DocumentSnapshot snapshot = await transaction.get(documentReference);
if (!snapshot.exists) {
throw Exception("User does not exist!");
}
// Update the follower count based on the current count
// Note: this could be done without a transaction
// by updating the population using FieldValue.increment()
// Perform an update on the document
transaction.update(documentReference, {'followers': FieldValue.increment(1);});
// Return the new count
return newFollowerCount;
})
.then((value) => print("Follower count updated to $value"))
.catchError((error) => print("Failed to update user followers: $error"));
You can see more documentations here: FlutterFire

DocumentID search in Firestore with a List

Can i search a Firestore DocumentID with a List<String>?
I am trying to search through my collection with some selection of documentID in a List. The List will consist of few String. Can I search through the Firestore collection using this?
This is the List:
List<String> _selectedBusStop = List<String>();
This is the code I used in finding the DocumentID based on the list that is in here.
Future <void> saveRoute(_selectedBusStop) async{
Firestore.instance.collection('markers').where('BusstopName', isEqualTo: _selectedBusStop)
.snapshots().listen((location) {
if(location.documents.isNotEmpty){
for (int i = 0; i < location.documents.length; i++){
initRoute(location.documents[i].data, location.documents[i]);
}
}
});
setState(() {
});
}
I am using where and isEqualTo or is this approach wrong? Any idea how to make it work for this part? Thank you in advance for your help.
Update:
This is how my Firestore looks like:
The List have some of the BusstopName but not all of it. I do not want to retrieve all the data from the Firestore just the one that is in the List. Sorry for causing so many misunderstanding.
Use the whereIn operator, like this:
Future <void> saveRoute(_selectedBusStop) async{
Firestore.instance.collection('markers').where('BusstopName', whereIn: _selectedBusStop)
.snapshots().listen((location) {
if(location.documents.isNotEmpty){
for (int i = 0; i < location.documents.length; i++){
initRoute(location.documents[i].data, location.documents[i]);
}
}
});
setState(() {
});
}
Assuming your documents have a unique id stored in the field BusstopName and also the documents actual id matches the content of this field, you have 2 possibilities.
(1) .where query
query data with collection("markers").where("BusstopName", "=", "yourBuststopId").
this returns a querySnapshot Object, on which you can call .size to check if there were any documents with that Id found (could be more than 1 if you have an inconsistent database).
(2) .doc query
query data with collection("markers").doc("yourBuststopId")
this returns a documentSnapshot Object, on which you can call .exist to check if the document actually exsists.
In both cases you need to do 1 query per Id, because Firestore queries only support equality and range operations. See this similar SO question. I would suggest to do the queries asynchronously, otherwise the time to execute will increase with the size of the array.
If you are concerned about costs, you only get billed for the results that actually return documents that exist.
you might also try this:
FirebaseFirestore.instance
.collection('markers')
.where('BusstopName', arrayContainsAny: ['Utar Bus Stop', 'Garden Bus Stop'])
.get()
.then(...);
Taken from the examples documentation