How can use firestore using where and orderby in flutter? - firebase

How can use firestore using where and orderby in flutter?
When I wanna to use both, I got the error.
Exception has occurred.
_CastError (Null check operator used on a null value)
code
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Posts')
.where('country', isEqualTo: user.country)
//.where('country', isEqualTo: 'Australia')
.orderBy('time', descending: true)
.snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
//print(user.country);
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) => Container(
margin: EdgeInsets.symmetric(
horizontal: width > webScreenSize ? width * 0.3 : 0,
vertical: width > webScreenSize ? 15 : 0),
child: PostCard(
snap: snapshot.data!.docs[index],
),
),
);
},
So, why I could not got the data? I'd got the user.value.

The problem is that you're telling Flutter that snapshot.data is guaranteed to have a value, when in reality it doesn't here:
return ListView.builder(
itemCount: snapshot.data!.docs.length,
I recommend reading the documentation for StreamBuilder again, as there are many more states than snapshot.connectionState == ConnectionState.waiting that you need to handle.
For example, there could be an error, or there could be no data for another reason:
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Posts')
.where('country', isEqualTo: user.country)
.orderBy('time', descending: true)
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
// 👇 Handle error
if (snapshot.hasError) {
return const Center(
child: Text(snapshot.error),
);
}
// 👇 Handle lack of data
if (!snapshot.hasData) {
return const Center(
child: Text("Something when wrong - no data available"),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) => Container(
margin: EdgeInsets.symmetric(
horizontal: width > webScreenSize ? width * 0.3 : 0,
vertical: width > webScreenSize ? 15 : 0),
child: PostCard(
snap: snapshot.data!.docs[index],
),
),
);

Related

I can't get data stream from firestore how do I fix this ØŸ

I tried fetching the data without using the StreamBuilder and all the data was fetched successfully but when I used the StreamBuilder it didn't work
StreamBuilder(
stream: Firestore.instance.collection('chats/IClRN96vdYSpdtfT4PZh/messeges').snapshots(),
builder: (ctx , snap) {
if(snap.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator(),);
}
return ListView.builder(
itemCount: snap.data.documents.length,
itemBuilder: (ctx, i) => Container(
padding: EdgeInsets.all(10),
child: Text('Text Chat messeges'),
));
})
replace snap.data.documents.length with snap.data.docs.length
add AsyncSnapshot<QuerySnapshot> to snap
StreamBuilder(
stream: Firestore.instance.collection('chats/IClRN96vdYSpdtfT4PZh/messeges').snapshots(),
builder: (ctx , AsyncSnapshot<QuerySnapshot> snap) {
if(snap.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator(),);
}
return ListView.builder(
itemCount: snap.data!.documents.length,
itemBuilder: (ctx, i) => Container(
padding: EdgeInsets.all(10),
child: Text('Text Chat messeges'),
));
})
**And before the documents put ! **

Failed assertion: line 1702 pos 12: 'center!.parent == this': is not true

What is the reason for getting the error?
And when I put the debug flag in the Streambuilder line, my application freezes before it comes to the main screen.
body: CustomScrollView(
slivers: [
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.limit(10)
.orderBy('id', descending: true)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> dataSnapshot) {
return !dataSnapshot.hasData
? SliverToBoxAdapter(
child: linearProgress(),
)
: SliverStaggeredGrid.countBuilder(
crossAxisCount: 1,
staggeredTileBuilder: (val) => StaggeredTile.fit(1),
itemBuilder: (context, index) {
DataModel model = DataModel.fromJson(
dataSnapshot.data!.docs[index].data()
as Map<String, dynamic>);
return sourceInfo(model, context);
},
itemCount: dataSnapshot.data!.docs.length);
},
),
],
),
There was no problem when I imported the relevant codes into SliverPadding. Edited code.
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.limit(10)
.orderBy('id', descending: true)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> dataSnapshot) {
return !dataSnapshot.hasData
? SliverPadding(
sliver: SliverToBoxAdapter(
child: ColorLoader(),
),
padding: EdgeInsets.all(0),
)
: SliverPadding(
sliver: SliverStaggeredGrid.countBuilder(
crossAxisCount: 1,
staggeredTileBuilder: (_) => StaggeredTile.fit(1),
itemBuilder: (context, index) {
DataModel model = DataModel.fromJson(
dataSnapshot.data!.docs[index].data()
as Map<String, dynamic>);
return sourceInfo(model, context);
},
itemCount: dataSnapshot.data!.docs.length),
padding: EdgeInsets.all(0),
);
},
),
According to this comment in a Github thread for a similar issue if the sliver being replaced is not the first it should work fine.
So a possible workaround is to add empty SliverToBoxAdapter() as first sliver before BodyContent().
There is more information and possible solutions in the Github thread, I recommend taking a look at it.

How to access data from firestore using streambuilder flutter

I want to access data from firestore but there are errors, how can i do that?
I cant use .docs in snapshot.
StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
Stream:
getChatRoomMessages(chatRoomId) async {
return FirebaseFirestore.instance.collection("chatRooms").doc(chatRoomId).collection("chats").orderBy("ts", descending: true).snapshots();}
in the StreamBuilder you have to use AsyncSnapshot in with your snapshot property. That was what got it working for me
StreamBuilder<QuerySnapshot>(
stream: DatabaseMethods().getChatRoomMessages(chatRoomId),
builder: (context, AsyncSnapshot snapshot) { <<<< insert here
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data!.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
I found a solution:
StreamBuilder<QuerySnapshot>(
stream: DatabaseMethods().getChatRoomMessages(chatRoomId),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data!.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),

i got this error when i am trying to use snapshot.data.docs.length in listview.buider: The getter 'docs' isn't defined for the type 'Object'

I am trying to fetch data from firebase to list all the documents in a listview builder the code is still not completed in term of displaying the database filed in the code. this is the error: The getter 'docs' isn't defined for the type 'Object'
Container(
child: StreamBuilder<Object>(
stream: _firestore
.collection('Patient')
.doc(_auth.currentUser.email)
.collection("Diabetes")
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount:
snapshot.data.docs.length, // here is the error "docs"
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshot.data.docs[index]; // also another error "docs"
return Container();
});
}
return Center(
child: CircularProgressIndicator(),
);
}),
)
You should replace snapshot.data.docs.length with snapshot.data.length
Container(
child: StreamBuilder<Object>(
stream: _firestore
.collection('Patient')
.doc(_auth.currentUser.email)
.collection("Diabetes")
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot = snapshot.data[index];
return Container();
});
}
return Center(
child: CircularProgressIndicator(),
);
}),
)
I solved the problem by replacing StreamBuilder<Object> with StreamBuilder<QuerySnapshot>. by default the StreamBuilder comes in this form StreamBuilder<Object>

Flutter/Dart Stream Builder Multiple Collections Firebase

I know there's probably a better way to do this but would like if its possible, to maintain the current DB structure.. (see attached)
DB Collections
Question: How can I return a StreamBuilder with a Listview(child:listTile) that displays profiles for all UID's that a particular user is following(eg: return user profiles that user "BHRaCBR.." is following). In this case im BHRaCBR...
Code below works but only returns one listTile (user):
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('following')
.doc('BHRaCBR..')
.collection('userFollowing')
.where('isApproved', isEqualTo: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.documents[index];
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('profile')
.where('uid', isEqualTo: ds['uid'])
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
final data0 = snapshot.data.docs;
return Container(
height: 200,
child: ListView.builder(
itemCount: data0.length,
itemBuilder: (BuildContext ctx, index) {
return Card(
child: ExpansionTile(
leading: CircleAvatar(
radius: 32,
backgroundImage: NetworkImage(
data0[index]
.data()['image_url']
.toString(),
),
),
title: Text(data0[index].data()['username']),
),
);
}),
);
});
});
});

Resources