how to retrieve the data from cloud Firestore in flutter? - flutter

We are trying to fetch the data from cloud Firestore but we unable to find that how admin fetch all the information about user like their appointment

Hope you are using the plugin cloud_firestore to fetch the data from the firestore
initialize the firestore with your credentials which can be copied from your google_services.json file
final FirebaseApp app = await FirebaseApp.configure(
name: 'test',
options: const FirebaseOptions(
googleAppID: '1:79601577497:ios:5f2bcc6ba8cecddd',
gcmSenderID: '79601577497',
apiKey: 'AIzaSyArgmRGfB5kiQT6CunAOmKRVKEsxKmy6YI-G72PVU',
projectID: 'flutter-firestore',
),
);
final Firestore firestore = Firestore(app: app);
to fetch your documents
CollectionReference get users=> firestore.collection('users');
await users.where('name', isEqualTo: 'neha').getDocuments();
or
Firestore.instance.collection('users').where('name', isEqualTo: 'neha')
.snapshots.listen(
(data) => print('grower ${data.documents[0]['name']}')
);

Related

How can I access each document id in Firebase?

In my blogapp ,I am trying to implement comment system in flutter using cloud firestore. Each document is a post and I am trying to add comments as a subcollection to each document. How can I access each document id so that I can access the subcollection ?
Here I tried to print the document id below but it shows error NoSuchMethodError: 'id' method not found Receiver: null Arguments: [] :
final ref = await FirebaseFirestore.instance
.collection('blogs')
.add({
'title': titleController.text,
'body': myController.text,
'author': name,
'date': DateFormat('dd/MM/yyyy,hh:mm')
.format(DateTime.now()),
})
.then((value) => successAlert(context))
.catchError((error) =>
errorAlert(context));
titleController.clear();
myController.clear();
print(ref.id);
}
This is my firestore database :
You need to have access to the document id inside blogs, and access it's collection and the add your data like this...
await FirebaseFirestore.instance
.collection('blogs')
.doc(documentId) // you need to enter this document id
.collection('comments').add({
'title': titleController.text,
'body': myController.text,
'author': name,
'date': DateFormat('dd/MM/yyyy,hh:mm')
.format(DateTime.now()),
})
When you dont have the document id Firebase provides the get() command which returns the content of a collection. Like this:
db.collection("cities").get().then((res) => print("Successfully completed"), onError: (e) => print("Error completing: $e"));
But i realize that you will need the document id, so to get this you have to store the id after inserting a post, i've an example from a personal project:
await firestore.collection('item').add({
'quantity': element.quantity,
'product_id': element.product.productId,
}).then((value) {
/// Here you can access [value.id] to get this document id.
/// Now you can save it in a list or a class instance. Just keep it.
})
Now you can use the document id to update the post with a new comment, like this. For more information we have the Firestore documentation with flutter code snipets.

How to update all collection in firebase firestore in flutter

I have two collections. One collection "User", who contains the user info (name...) And one collection "Post" who contains all posts of my flutter application. A post document contains many fields like a "Title", "Name" of the user. I add an option in my application to allow the user to change his name. But I must change the name in the "User" collection and in all posts it creates in the "Post" collection. How should I do it? Can anyone help me with an example?
There's nothing magical here. You'll need to get all post documents for that user with a query, and then update them one by one or in batches.
I'd also recommend checking out: What is the fastest way to write a lot of documents to Firestore?
Depends on which firestore are you using.
For Cloud Firestore:
You can update like this way, this is the case where you are updating just one field of your user.
final docRef = db.collection("users").doc("user_id");
final updates = <String, dynamic>{
"timestamp": FieldValue.serverTimestamp(),
};
docRef.update(updates).then(
(value) => print("DocumentSnapshot successfully updated!"),
onError: (e) => print("Error updating document $e"));
For updating a nested field:
// Assume the document contains:
// {
// Title: "Post Tittle",
// Name: "Post Name"
// user: { id: "1", name: "User Name" }
// date: "2022-12-08"
// }
db
.collection("posts")
.doc("post_id")
.update({"date": "2022-13-08", "user.name": "New name"});
You can see more details here: https://firebase.google.com/docs/firestore/manage-data/add-data
Assuming there is a user id attached to each post, you can query from the posts collection where the user (that is changing his/her name) id matches the id that is in the post (from the posts collection) and then modify the user property/attribute from the results.
A sample code would look like this,
To modify from the user collection
final docRef = FirebaseFirestore.instance
.collection('users')
.doc(id);
final response = await docRef
.update(updatedDateInJson)
.then((value) => value)
.onError((error, stackTrace) => error);
To modify from the posts collection where the user is found in a post
final response = FirebaseFirestore.instance
.collection('posts')
.where('name', isEqualTo: 'John')
.get()
.then((value) async {
// modify each doc
});
Quick Note: use a onError block to check for errors in updating docs.

FLUTTER / FIRESTORE - Retrieving DATA which is nested in several subcollections

I have created a database using Firestore. The main collection is "familyAccounts". Inside each account : you have info, and a subcollections of USERS (each account offers two Users (two differents user profiles), which have data too... So data is nested in various subcollections.
Here is how I "set" data in the database :
final _fireStore = FirebaseFirestore.instance;
//
if (newUser != null) {
_fireStore
.collection('familyAccounts')
.doc(email)
.set({
'name': '$name $firstName',
'country': country,
'region': region,
});
_fireStore
.collection('familyAccounts')
.doc(email)
.collection('users')
.doc('user1')
.set({
'userId': 'Utilisateur n°1',
'teacherCode': '',
'avatar': 'icons/avatar.jpg',
'vocLists': [],
});
_fireStore
.collection('familyAccounts')
.doc(email)
.collection('users')
.doc('user2')
.set({
'userId': 'Utilisateur n°2',
'teacherCode': '',
'avatar': 'icons/avatar.jpg',
'vocLists': [],
});
This works fine. But now, no matter what I try, I just do not understand how to retrieve this data. It was so easy to add it to the database. I have been reading online and am totally lost.
To make it as clear as possible : when the user logs in the app : he/she types in email and password : if account info is correct (using firebase_auth (this works)) then, I want to retrieve the data for both users linked to the account. Once I get the data, I use Provider to make it accessible wherever it will be needed in the app.
Can someone Help ? Thanks in advance :)
So far : I have managed to do this : I have created a function :
final _fireStore = FirebaseFirestore.instance.collection('familyAccounts');
getUserById(String id) async {
final DocumentSnapshot doc = await _fireStore.doc(id).get();
print(doc.data());
print(doc.id);
print(doc.exists);
}
It gives me the "first level" of data... But how can I dig deeper...?

Flutter cloud_firestore persistence is not working even if it is enabled

I've done tons of searches on this. But, my flutter app is working nice on the active network. I've enabled persistence for cloud_firestore, but it's showing this error:
[cloud_firestore/unavailable] The service is currently unavailable. This is a most likely a transient condition and may be corrected by retrying with a backoff.
My sample code:
FirebaseFirestore db = FirebaseFirestore.instance;
db.settings = Settings(persistenceEnabled: true, cacheSizeBytes: 10000000);
final ref = db.doc("some_collection/some_doc");
try{
ref.update({"key": value});
} catch(error) {
print(error.toString());
}
My pubspec.yaml:
firebase_messaging: ^8.0.0-dev.14
firebase_core: ^0.7.0
firebase_auth: ^0.20.0+1
flutter_local_notifications: ^3.0.3
cloud_firestore: ^0.16.0
So, my scenario was, I had to upload some data to firestore whenever my application receives an incoming message from my client. That's why I needed two services, one is background message receiver and firestore persistence.
What I was doing:
Trying to read some data from the firestore first and based on that I need to put the incoming message data to the firestore again. Something like this:
FirebaseFirestore db = FirebaseFirestore.instance;
db.settings = Settings(persistenceEnabled: true, cacheSizeBytes: 10000000);
// payments ref
final paymentRefs = db
.collection("payments")
.where("trxID", isEqualTo: "123456")
.where("amount", isEqualTo: 50)
.limit(1);
try {
final paymentGet = await paymentRefs.get();
if (paymentGet.size > 0) {
final paymentData = paymentGet.docs[0];
// check for payment existence with the trxID
// if exists, then validate and update
if (paymentData.exists) {
final paymentAmount = paymentData.data()['amount'];
final exactPaymentRef = db.collection("payments").doc(paymentData.id);
// for individual and if amount matches
if (amount == paymentAmount) {
exactPaymentRef.update({
"paid": true
});
}
} else {
// payment ref not found with trxID
// so upload the trxID to reqTrxID collection
db.doc("reqTrxID/$trxID").set({
"createdAt": new DateTime.now().millisecondsSinceEpoch,
"phoneNumber": phoneNumber,
"amount": amount
});
}
}
} catch (error) {
print("error triggering to firestore: ${error.toString()}");
}
My mistake was, I was doing some extra fetchings from the firestore. And as firebase documentation firestore persistence won't work on any asynchronous (try/catch, promise, async/await) way (that I was doing so happily :) ).
How I solved this:
FirebaseFirestore db = FirebaseFirestore.instance;
db.doc("reqTrxID/$trxID").set({
"createdAt": new DateTime.now().millisecondsSinceEpoch,
"phoneNumber": phoneNumber,
"amount": amount
});
I simply just upload the value I had to, and my all necessary checking I send them to cloud function on document create trigger. That's solved my problem.

Flutter: add data to Map (instead of replacing data)

The following transaction completely replaces the data in a Firestore Map when run:
DocumentSnapshot docSnapshot = await tx.get(docRef); // doc Snapshot
if (docSnapshot.exists) {
await tx.update(
docRef,
<String, dynamic>{
'Users': {
'user.uid': {'name': user.displayName, 'date': DateTime.now()},
}
},
);
What would be the correct way to add to a map instead of replacing the existing data, the same way FieldValue.arrayUnion works?
Since you already fetched the data you could take the map out from the snapshot, replace the data there and call the update with the altered map.