How to get snapshot metadata Firestore? - firebase

I need get snapshot metadata so can check if write to Firestore successful. I look at source and see there is SnapshotMetadata and boolean hasPendingWrites(). But there is no example how to implement and I cannot find anywhere.
I need implement so can show in my chat app if message is sent or still sending.
My code:
child: new FirestoreAnimatedList(
query: Firestore.instance.collection('Collection')
.orderBy('timestamp', descending: true)
.snapshots(),
padding: new EdgeInsets.all(8.0),
reverse: true,
itemBuilder: (_, DocumentSnapshot snapshot,
Animation<double> animation, int x) {
return new Chat(
snapshot: snapshot, animation: animation);
},
),
I cannot find how get SnapshotMetadata in query and feed into itemBuilder so I can show progressIndicator if sending.
Anyone know solution?
Thanks!

You can show progress bar using snapshot.connectionState
if(snapshot.connectionState == ConnectionState.waiting) {
return Text('Loading');
}

Related

Flutter - How to show ArrayList items pulled from Firebase Firestore with ListTile?

I have a build on Firebase Firestore like this:
In the structure here, there are 2 ArrayLists. I want to display what will be done from 2 ArrayLists as ListTile.
I tried a code like this:
Expanded(
child: StreamBuilder <QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("users").doc(FirebaseAuth.instance.currentUser.uid).collection("yapilacaklar").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return Expanded(
child: _buildList(snapshot.data),
);
},
)
),
Widget _buildList(QuerySnapshot snapshot) {
return ListView.builder(
itemCount: snapshot.docs.length,
itemBuilder: (context, index) {
final doc = snapshot.docs[index];
return ListTile(
title: Text(doc["yapilacaklar"].toString()),
);
},
);
}
These codes I tried do not give an error, but they do not show in any Widget. How can I do what I want? Thanks in advance for the help.
I believe the issue is the '.collection("yapilacaklar")'. It will try to find a collection with the id "yapilacaklar" and your user doc doesn't have any collections. Yapilacaklar, in this case, is a field in the document. Try getting the snapshots of the actual document and then creating a ListView from the array in the yapilacaklar field.
The flutterfire documentation is very helpful for reading firestore data: https://firebase.flutter.dev/docs/firestore/usage/#read-data

retrieving current user to show in personal profile

hi im trying to retrive current user info from firebase but its showing me errors this error
this is my code
final auth = FirebaseAuth.instance;
final db = FirebaseFirestore.instance;
User? user = FirebaseAuth.instance.currentUser;
Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: StreamBuilder(
stream: db
.collection("Users")
.doc("list_students")
.collection("Students")
.doc(user!.uid)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center();
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Stack;
this is a screenshots of my firebase
First of all, try to print 'snapshot' and 'snapshot.data' for you've got proper data from firebase.
You need to cast snapshot.data as a List type before you can call the length method on snapshot.data. I cannot tell from your included code what is the underlying type for snapshot.data.
Another way is to specify AsyncSnapshot<List<String>> snapshot in the builder header, assuming the underlying data type is a List<String>.

Manually add item to flutter Stram builder in flutter

I have made flutter streambuilder that creates a flutter listview from results returned from a query.
StreamBuilder<QuerySnapshot>(
stream: _usersStream,
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
scrollDirection: Axis.horizontal,
children: snapshot.data!.docs.map(
(DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
addChildBtn();
return ListCard(
firstName: data['childFirstName'],
lastName: data['childLastName'],
points: data['points'],
);
},
).toList(),
);
},
),
It returns a listCard, a custom widget I made which consists of a container. However, I want to have a container always in the listview, regardless if there any items returned from the steam or not.
I have the same exact question. did you find an intelegent away for that?
my workaround which is not super, I added one document in firestore with specfic name, then in the list view builder I check for the name, if matched I return my fixed customized item, if doesn't match then I return the regular card.
the result is what you want, the constrain is that if you have different categories in your firestore database, then you will need to add this specific document everywhere.

Flutter FirebaseFirestore where condition returning related and unrelated values

I am querying a firestore collection in Flutter using where and arrayContains, for some reason it is not working as expected for me.
StreamBuilder(
stream: (_searchTerm.length >= 3)
? FirebaseFirestore.instance.collection("users").snapshots()
: FirebaseFirestore.instance
.collection('users')
.where('email', arrayContains: _searchTerm)
.snapshots(),
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
final results = snapshot.data.docs;
print(results.length);
return ListView.builder(
shrinkWrap: true,
itemCount: results.length,
itemBuilder: (ctx, index) => Text(
results[index].data()['display-name'],
),
);
})
The _searchTerm variable is populated as I type in some values into the textfield and when it hits a length of three characters that's when the above query fires.
For example when I type in test the query should only return the values that contain test in it, but I am getting the whole collection with and without the value test.
Please advice!
EDIT - Posting a screenshot of my firestore data structure
When you do the following:
FirebaseFirestore.instance
.collection('users')
.where('email', arrayContains: _searchTerm)
.snapshots(),
You are looking for documents inside the users collection that have _searchTerm as an item of the email array, property of a user document.
There are two problems:
I don't think the email property of your users is an array.
Firebase does not perform substring searches
I think you will need to use a third-party application for searches on Firestore. A popular one is Algolia that comes with a quite powerful FREE plan.

Do cloud firestore snapshot reads all the documents in the collection?

I'm creating a chat screen. What I'm currently doing is that I'm using a Streambuilder to listen to the 'messages' collection and display the messages using ListView.builder().
Below is the code i'm using.
StreamBuilder<QuerySnapshot>(
stream: _fireStoreInstance
.collection('$collectionName/$docID/messages')
.orderBy('sentAt', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
List<Map> documents = snapshot.data.docs
.map((doc) => {'documentId': doc.id, ...doc.data()})
.toList();
return ListView.builder(
cacheExtent: MediaQuery.of(context).size.height,
reverse: true,
itemCount: documents.length,
padding:
const EdgeInsets.only(left: 15.0, right: 15.0, bottom: 5.0),
itemBuilder: (context, index) {
return MessageBubble(
...
);
},
);
},
),
My concern is, will the query fetch all the documents in the collection all at once? If yes then it will be a lot of reads each time the query is executed
_fireStoreInstance
.collection('$collectionName/$docID/messages')
.orderBy('sentAt', descending: true)
.snapshots();
Do I need to paginate by using limit ? If I paginate how do I listen to new messages ? Thank you for your help.
Yes, .snapshots() will read and keep listening to all documents that fit the query, if you want a subset of that you will have to paginate it using .limit().
I have found this article, with a video step by step on How to perform real-time pagination with Firestore with the use of an infinite scroll. I think this is exactly what you looking for, so I won't post any code since you can follow that example.

Resources