I want to stream documents from my collection orders.
Here I stream all documents in my collection orders where the parameter progress is equal to pool.
This is how I do it:
Stream<List<Order>> streamOrderPool() {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = auth.currentUser;
final uid = user!.uid;
var ref = _db.collection('orders').where('progress', isEqualTo: 'pool');
return ref.snapshots().map(
(list) => list.docs.map((doc) => Order.fromJson(doc.data())).toList());
}
What I want to do is to remove all documents where the parameter dismissedIds contains uid.
This is how I solved it in a futurebuilder:
Future<List<Order>> getOrdersPool() async {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = auth.currentUser;
final uid = user!.uid;
var ref = _db.collection('orders').where('progress', isEqualTo: 'pool');
var snapshot = await ref.get();
var data = snapshot.docs.map((s) => s.data());
var orders = data.map((d) => Order.fromJson(d));
var orderslist = orders.toList();
orderslist.removeWhere((order) => order.dismissedIds.contains(uid));
orderslist.sort((b, a) => a.startDate.compareTo(b.startDate));
return orderslist;
}
How do I get the same result in a streambuilder, is it possible to use removeWhere somehow? How do I remove all documents from stream where dissmissedIds contains uid?
Related
Why is returning Instance of 'Future<String?>' instead String value?
Future<String?> getUser() async {
User user = await FirebaseAuth.instance.currentUser!;
FirebaseFirestore firestore = await FirebaseFirestore.instance;
String uid = user.uid;
String? userName;
// to get username from firebase
return firestore
.collection("users")
.doc(uid)
.get()
.then((value) {
if (value.exists) {
var data = value.data();
userName = data?["name"];
print("There is data :$userName");
} else {
print("There no Data!");
}
return Future.value(userName);
});
}
I am trying to get String value?
The place you like to get data from this method use await & the method is needed to be async. like
_myFunction() async{
final value = await getUser();
Also I will suggest to not mixing await and .then.
Future<String?> getUser() async {
User user = FirebaseAuth.instance.currentUser!;
FirebaseFirestore firestore = FirebaseFirestore.instance;
String uid = user.uid;
String? userName;
// to get username from firebase
final value = await firestore.collection("users").doc(uid).get();
if (value.exists) {
var data = value.data();
userName = data?["name"];
print("There is data :$userName");
} else {
print("There no Data!");
}
return userName;
}
I am having the data in the collection and when i try to read the data its showing the collection is empty.
My query to add the data to the Firestore
addAccount() async {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
User? user = FirebaseAuth.instance.currentUser;
AccountModel accountModel = AccountModel();
accountModel.uid = user?.uid;
accountModel.accountId = generateAccountNumber();
accountModel.accountName = nameTextController.text;
accountModel.currency = 'INR';
accountModel.amountBalance = data[2];
accountModel.isAvailable = "Y";
accountModel.accountType = data[1] == 'Savings' ? 'Savings' : 'Credit Card';
myProgressIndicator(context);
await firebaseFirestore
.collection("accounts")
.doc(user?.uid)
.collection(nameTextController.text)
.doc(generateAccountNumber())
.set(accountModel.toMap());
Get.to(AddCashAccount());
}
can anyone please help me where i am making the mistake.
I am integrating the following system into my to-do app:
Every time the user opens the app, it should check whether the date stored in Cloud Firestore has been exceeded.
If this is the case, all To-Dos of the user should be reset to false.
This is the date in Cloud Firestore I’m looking for:
This function should check if the date has been exceeded:
Future<bool> checkTime() async{
DateTime now = DateTime.now();
var query = users.where('Startdatum', isLessThanOrEqualTo: now);
query = query.where('userID', isEqualTo: userID);
final querySnapshot = await query.get();
return querySnapshot.size > 0;
}
And this function should reset all To-Dos to false:
Future allFalse() async{
return await users.doc(userID).get().then((DocumentSnapshot doc) {
var updateMap = new Map();
var toDos = doc['Level'];
for (var item in toDos.keys) {
updateMap[item] = false;
}
doc.reference.update({'Level' : updateMap});
});
}
I created both functions in a separate file (database), as you can see here:
class DatabaseService {
String userID;
DatabaseService(this.userID);
final CollectionReference users =
FirebaseFirestore.instance.collection('users');
Future allFalse() async {
return await users.doc(userID).get().then((DocumentSnapshot doc) {
var updateMap = new Map();
var toDos = doc['Level'];
for (var item in toDos.keys) {
updateMap[item] = false;
}
doc.reference.update({'Level': updateMap});
});
}
Future<bool> checkTime() async {
DateTime now = DateTime.now();
var query = users.where('Startdatum', isLessThanOrEqualTo: now);
query = query.where('userID', isEqualTo: userID);
final querySnapshot = await query.get();
return querySnapshot.size > 0;
}
}
I create an if condition in in inite State that includes checkTime. If checkTime returns true, the Future returns allFalse, which sets all To-Dos to false.
class _UebersichtState extends State<Uebersicht> {
User? user;
late DatabaseService database;
Future<void> connect() async{
final FirebaseAuth auth = FirebaseAuth.instance;
UserCredential result = await auth.signInAnonymously();
user = result.user;
database = DatabaseService(user!.uid);
}
#override
void initState() {
// TODO: implement initState
super.initState();
connect();
Future.delayed(Duration(seconds: 3), () async{
if(await database.checkTime()) {
return await database.allFalse();}
else print('Still time left');
});
}
I used a delay because the connect () function has to be executed first, it initializes database.
When I start the app, no error appears, but the To-Dos are not reset either.
Today we have the 21. 12. 2021 and in Cloud Firestore is 14. 12. 21 deposited.
The function allFalse works, it resets the To-Dos all.
It must be the function checkTime, which does not return a bool in the if condition. I just replaced it with if (0 == 0) and that triggers allFalse.
Can someone help me?
This is just a guess, but I believe this is the problem:
query = query.where('userID', isEqualTo: userID);
The above line would only work if your document had a field userID and said field was equal to your UID, but from what I could gather, you identify the UID by the name of the documents, if that is the case, this should work?
Future<bool> checkTime() async {
CollectionReference users = FirebaseFirestore.instance.collection('users');
final now = DateTime.now();
final doc = await users.doc(userID).get();
final stufenzeit = (doc.data() as Map<String, dynamic>)['Stufenzeit'] as Map<String, dynamic>;
final storedDate = (stufenSetit['Startdatum'] as TimeStamp).toDate();
return now.compareTo(storedDate) > 0;
}
There's probably also a way to do it with queries, but I am not so well versed on those to be completely honest.
I want when a new user registers then in the userProfile collection there I should be able to set a unique id to each user like
P-_____
If you are using firebase authentication then you can do the following
final String Uid = FirebaseAuth.instance.currentUser.uid;
final firestore = FirebaseFirestore.instance;
firestore.collection(collectionPath).doc("P-"+Uid).set(data);
Alternatively, if you are not using FirebaseAuth then you can do the following
final String Uid = FirebaseAuth.instance.currentUser.uid;
final firestore = FirebaseFirestore.instance;
firestore.collection(collectionPath).doc("P-"+getRandomString(10)).set(data); //random string with 10 charecter
Code to generate a random string
const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
Random _rnd = Random();
String getRandomString(int length) => String.fromCharCodes(Iterable.generate(
length, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))));
The add method adds the new document to your collection with a unique auto-generated ID. If you'd like to specify your own ID, call the set method on a DocumentReference instead:
CollectionReference users = FirebaseFirestore.instance.collection('users');
Future<void> addUser() {
return users
.doc('ABC123')
.set({
'full_name': "Mary Jane",
'age': 18
})
.then((value) => print("User Added"))
.catchError((error) => print("Failed to add user: $error"));
}
Calling set with a id that already exists on the collection will replace all the document data.
Hello I'm using flutter and firebase so I have firestore I have on collocation name Institutes and in document has names of Institutes and my Fields I have profile data ….no I need update some fields by where conditions where currant user = Key User id in the fields*
Screenshot
onPressed: ()async {
final FirebaseAuth auth = FirebaseAuth.instance;
final user = await auth.currentUser();
final iduser = user.uid;
final emailuser = user.email;
final snapshot = await Firestore.instance.collection("Institute")
.document(_Institute_name.text).get();
if (snapshot.exists) {
print(this name is existd);
} else {
await DataBaseService(email: emailuser,
uid: iduser,
Document: _Institute_name.text)
.CreateCollectionInofwithImage(
_Institute_name.text, Institute_address.text,
int.parse(Institute_phone.text), _image).then((isdone) {
setState(() {
Institute_address.clear();
Institute_phone.clear();
_Institute_name.clear();
_image = null;
});
});
}
}
Okay try this
onPressed: ()async {
final FirebaseAuth auth = FirebaseAuth.instance;
final user = await auth.currentUser();
final iduser = user.uid;
final emailuser = user.email;
QuerySnapshot snapshot = await Firestore.instance
.collection('Institute')
.where('user id', isEqualTo: iduser)//I think this is your field name from the
//picture it looks like theres a space in it
.getDocuments();
if (snapshot != null) {
Map<String,dynamic> document = snapshot.documents[0].data;
//Then you would reference this by document['fieldName']
} else {
await DataBaseService(email: emailuser,
uid: iduser,
Document: _Institute_name.text)
.CreateCollectionInofwithImage(
_Institute_name.text, Institute_address.text,
int.parse(Institute_phone.text), _image).then((isdone) {
setState(() {
Institute_address.clear();
Institute_phone.clear();
_Institute_name.clear();
_image = null;
});
});
}
}