I am trying to implement a request button that if click on it should turn into a request send the way Facebook works
I tried to implement this But I am having issues
Below is the approach I used
class _TherapistRequestState extends State<TherapistRequest> {
final Stream<QuerySnapshot> therapists = FirebaseFirestore
.instance.collection('users')
.where('role', isEqualTo: 'Therapist')
.snapshots();
final _auth = FirebaseAuth.instance;
String ? therapist;
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title:Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'MAISHA BORA',
style: GoogleFonts.aclonica(
textStyle:const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20,
),
),
),
],
),
backgroundColor: kPrimaryColor.withOpacity(0.9),
),
body: Column(
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Available Therapist',
style: GoogleFonts.aclonica(
color: kPrimaryColor,
fontSize: 25,
fontWeight: FontWeight.bold
),
),
],
),
const Divider(
color: kPrimaryColor,
height: 20,
),
StreamBuilder(
stream: therapists,
builder: (context, AsyncSnapshot snapshot){
if(snapshot.hasData){
final data = snapshot.requireData;
return ConstrainedBox(
constraints: BoxConstraints.tightFor(
height: size.height * 0.7,
width: size.width
),
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: data.size,
itemBuilder: (context, i){
therapist = data.docs[i]['uid'];
return Column(
children: [
Card(
shadowColor: Colors.grey,
elevation: 10.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Dr ${data.docs[i]['username']}',
style: GoogleFonts.acme(
textStyle:const TextStyle(
color: Colors.black,
fontSize: 20,
),
),
),
Text(
'Patients ${data.docs[i]['patients']}/4',
style: GoogleFonts.aladin(
textStyle: const TextStyle(
color: Colors.grey,
fontSize: 20,
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
buildButton(context),
],
),
],
),
),
),
],
);
}
),
);
}
else{
return Container();
}
},
),
],
),
);
}
Widget buildButton(context){
return StreamBuilder(
stream: FirebaseFirestore.instance.collection('users').doc(therapist).collection('request').doc(_auth.currentUser!.uid).snapshots(),
builder: (context, AsyncSnapshot snapshot){
if(snapshot.data.exists){
return SquareButton(
label: 'Request Sent',
color: Colors.grey,
onPressed: (){
null;
}
);
}
return SquareButton(
label: 'Request',
color: Colors.green,
onPressed: () async{
FirebaseFirestore.instance.collection('users')
.doc(therapist)
.collection('request')
.doc(_auth.currentUser!.uid)
.set({
'userId' : _auth.currentUser!.uid,
}).then((value) {
showToast(
message: 'Request sent successfully',
color: Colors.green,
);
});
},
);
}
);
}
}
But when I use this, if I go to the page I get this error
The following NoSuchMethodError was thrown building StreamBuilder flutter
which I suppose is when I try to check the state of the button
How can tackle this using a different method.
Please do assist me on this
CodePudding user response:
I would suggest that instead of using a stream, you can fetch the data from firebase once. To do that, you can define a future on top of your state and assign it a value in your initState
In your build method you can use a FutureBuilder around the button you want to customize
EDIT You can do something like this:
class _TherapistRequestState extends State<TherapistRequest> {
Future required_document;
initHelper()async{ //using this function because we need to use async await
required_document = await FirebaseCollection.......doc();
}
initState(){
initHelper();
}
Widget build(BuildContext context){
return Container();
// enclose your button that needs to be customized in a FutureBuilder like so:
// FutureBuilder(
// future: required_document,
// builder:(a,b){return ElevatedButton()}
//)
}
}
