Flutter - setState() or markNeedsBuild() called during build - flutter

Showing Error While loading post from Firebase Cloud.. I am using provider in my Application
setState() or markNeedsBuild() called during build.
Detailed Error
════════ Exception caught by foundation library ════════════════════════════════
The following assertion was thrown while dispatching notifications for PostFunctions:
setState() or markNeedsBuild() called during build.
This _InheritedProviderScope<PostFunctions> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
My Code When I Load Post..
Widget feedBody(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.orderBy('time', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: SizedBox(
height: 200.0,
width: 200.0,
child: Lottie.asset('assets/animations/loading.json'),
),
);
} else {
return loadPosts(context, snapshot);
}
},
),
height: MediaQuery.of(context).size.height * 0.80,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: constantColors.darkColor.withOpacity(0.6),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(18.0),
topRight: Radius.circular(18.0),
),
),
),
),
);
}
My Load Post Code
Widget loadPosts(
BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data.docs.map((DocumentSnapshot documentSnapshot) {
Provider.of<PostFunctions>(context, listen: false)
.showTimeAgo(documentSnapshot.data()['time']);
return Container(
height: MediaQuery.of(context).size.height * 0.62,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
top: 8.0,
left: 8.0,
),
child: Row(
children: [
GestureDetector(
onTap: () {
if (documentSnapshot.data()['useruid'] !=
Provider.of<Authenticationss>(context, listen: false)
.getUserUid) {
Navigator.pushReplacement(
context,
PageTransition(
child: AltProfile(
userUid: documentSnapshot.data()['useruid'],
),
type: PageTransitionType.bottomToTop,
),
);
}
},
child: CircleAvatar(
backgroundColor: constantColors.blueGreyColor,
radius: 20.0,
backgroundImage:
NetworkImage(documentSnapshot.data()['userimage']),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Container(
width: MediaQuery.of(context).size.width * 0.6,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: Text(
documentSnapshot.data()['caption'],
style: TextStyle(
color: constantColors.greenColor,
fontWeight: FontWeight.bold,
fontSize: 16.0),
),
),
Container(
child: RichText(
text: TextSpan(
text: documentSnapshot.data()['username'],
style: TextStyle(
color: constantColors.blueColor,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
children: <TextSpan>[
TextSpan(
text:
' , ${Provider.of<PostFunctions>(context, listen: false).getImageTimePosted.toString()}',
style: TextStyle(
color: constantColors.lightColor
.withOpacity(0.8),
),
)
],
),
),
),
],
),
),
),
Container(
width: MediaQuery.of(context).size.width * .2,
height: MediaQuery.of(context).size.height * 0.05,
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('awards')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView(
scrollDirection: Axis.horizontal,
children: snapshot.data.docs
.map((DocumentSnapshot documentSnapshot) {
return Container(
height: 30.0,
width: 30.0,
child: Image.network(
documentSnapshot.data()['award']),
);
}).toList(),
);
}
},
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
height: MediaQuery.of(context).size.height * 0.45,
width: MediaQuery.of(context).size.width,
child: FittedBox(
child: Image.network(
documentSnapshot.data()['postimage'],
scale: 2,
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Padding(
padding: const EdgeInsets.only(left: 21.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 80.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onLongPress: () {
Provider.of<PostFunctions>(context, listen: false)
.showLikes(
context,
documentSnapshot.data()['caption'],
);
},
onTap: () {
print('adding like');
Provider.of<PostFunctions>(context, listen: false)
.addLike(
context,
documentSnapshot.data()['caption'],
Provider.of<Authenticationss>(context,
listen: false)
.userUid);
},
child: Icon(
FontAwesomeIcons.heart,
color: constantColors.redColor,
size: 22.0,
),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('likes')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
snapshot.data.docs.length.toString(),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
);
}
},
)
],
),
),
Container(
width: 80.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
Provider.of<PostFunctions>(context, listen: false)
.shotCommentSheets(context, documentSnapshot,
documentSnapshot.data()['caption']);
},
child: Icon(
FontAwesomeIcons.comment,
color: constantColors.blueColor,
size: 22.0,
),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('comments')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
snapshot.data.docs.length.toString(),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
);
}
},
)
],
),
),
Container(
width: 80.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onLongPress: () {
Provider.of<PostFunctions>(context, listen: false)
.showAwardPresenter(context,
documentSnapshot.data()['caption']);
},
onTap: () {
Provider.of<PostFunctions>(context, listen: false)
.showReward(context,
documentSnapshot.data()['caption']);
},
child: Icon(
FontAwesomeIcons.award,
color: constantColors.yellowColor,
size: 22.0,
),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('awards')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
snapshot.data.docs.length.toString(),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
);
}
},
)
],
),
),
Spacer(),
Provider.of<Authenticationss>(context, listen: false)
.getUserUid ==
documentSnapshot.data()['useruid']
? IconButton(
icon: Icon(
EvaIcons.moreVertical,
color: constantColors.whiteColor,
),
onPressed: () {
Provider.of<PostFunctions>(context, listen: false)
.showPostOptions(context,
documentSnapshot.data()['caption']);
},
)
: Container(
height: 0.0,
width: 0.0,
),
],
),
),
),
],
),
);
}).toList());
}
}

As the error describes, setState is called even before the build function is completed.
You might not see any issue in you UI when this exception hits on debug or local release mode. But exceptions like these displays a grey screen or something instead of the desired widget on google play release etc.
It means you are try to refresh the page even while the initial widget is already loading.
To prevent calling setState during build method is already in progress, you can check whether your initial widget is mounted properly before calling setState. For doing that just wrap your setState by if statement like this :
if(mounted){
setState((){
});
}
There is also another method with is called after build method is completed. Follow this question to know more : Is there any callback to tell me when "build" function is done in Flutter?

Related

Passing data from page to page firebase flutter

I am trying to pass firebase snapshot data from first page to second page in flutter using GET. I'm able to pass data from one screen to another in debug mode but not in release mode.
I have used a streambuilder on the page and a Future on second . Please where am i going wrong ?
here is code..
first page:
Container(
child: Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Songs')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return Container(
color: Colors.white24,
padding: EdgeInsets.all(10),
child: ListView(
children: snapshot.data!.docs.map((document) {
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
side: BorderSide(
color: Colors.purple, width: 2)),
elevation: 4,
child: ListTile(
title: Text(document['title'],
style: TextStyle(fontSize: 16)),
subtitle: Text(
document['artist'],
style: TextStyle(color: Colors.purple),
),
onTap: () {
Get.to(() => DetailsPage(
piss: document,
post: document.id,
));
},
contentPadding: EdgeInsets.all(20),
leading: Image.asset('assets/logo.png'),
trailing: document['isNew'] == true
? Image.asset(
'assets/new.gif',
)
: null),
),
);
}).toList(),
),
);
}),
),
),
_banner == null
? Container()
: Container(
margin: const EdgeInsets.only(bottom: 12),
height: 52,
child: AdWidget(
ad: _banner!,
),
),
],
),
),
);
}
}
second page
FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Expanded(
child: ListView.builder(
itemCount: widget.piss['tileHeaders'].length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
setState(() {
_index = index;
counter = counter + 1;
print('COUNTER: $counter');
if (counter == 3) {
_showRewardedAd();
_controller.play();
print("Counter is $counter");
counter = 0;
_createRewardedAd();
}
});
index > 0
? playIt(index)
: _controller
.load(widget.piss['videos'][index]);
},
child: Card(
elevation: 5,
child: Column(
children: [
Container(
height: 100,
child: Row(
children: [
Center(
child: Padding(
padding: EdgeInsets.all(10),
child: Expanded(
child: Image.asset(
"assets/logo.png"),
flex: 2,
// flex: 2,),
),
)),
Expanded(
child: Container(
alignment:
Alignment.topLeft,
child: Column(
children: [
Expanded(
flex: 5,
child: ListTile(
title: Text(
widget.piss[
'tileHeaders']
[index],
style: TextStyle(
fontSize:
26)),
),
),
Expanded(
flex: 5,
child: Row(
mainAxisAlignment:
MainAxisAlignment
.end,
children: [
Container(
child: widget
.piss[
'videos']
[
index]
.toString()
.contains(
'PL')
? Center(
child:
Container(child: playlist()),
)
: Center(
child:
Container(
child:
notPlaylist(),
),
),
),
],
))
],
)),
)
],
))
],
)),
);
}),
);
}
})
Please help

Gesture detector on tap not working in flutter release app but working in debug app

I am using firestore and created 4 cards on which the user taps on goes to the next screen. Everything is working fine in debug mode, in debug mode both Inkwell and Gesture Detector are working but when I make a release version I don't know why but both Inkwell and Gesture Detector are not working. Have no idea what's causing this. Please help.
class _RestaurantDashboardState extends State<RestaurantDashboard> {
Widget buildRestaurantCards(String title, IconData iconData, int orderCount) {
return Expanded(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
if (title == "Menu\nManagement") {
Navigator.push(context,
MaterialPageRoute(builder: (context) => MenuManagement()));
} else if (title == "Current Orders") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OrderScreen("In Progress"),
),
);
} else if (title == "Order History") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OrderHistory("In Progress"),
),
);
} else if (title == "Update Profile") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RestaurantSignUp(Utils.restaurant!.restaurantId, true),
),
);
}
},
child: Container(
height: double.infinity,
child: Card(
margin: EdgeInsets.all(8),
elevation: 8,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
orderCount > 0
? Row(
children: [
Container(
alignment: Alignment.center,
width: 30,
height: 30,
margin: EdgeInsets.all(4),
padding: EdgeInsets.all(4),
child: FittedBox(
child: Text(
orderCount.toString(),
style: TextStyle(
color: Colors.white, fontSize: 18),
)),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(16),
),
)
],
)
: SizedBox(),
Container(
margin: EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerRight,
child: Icon(
iconData,
size: 40,
),
),
],
),
),
Container(
width: double.infinity,
margin:
EdgeInsets.symmetric(horizontal: 16, vertical: 16),
alignment: Alignment.center,
child: FittedBox(
child: Text(
title,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w600),
textAlign: TextAlign.center,
),
)),
],
)),
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
),
body: Container(
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * 0.25,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
isFirebaseInitialized
? StreamBuilder(
stream: FirebaseFirestore.instance
.collection("orders")
.snapshots(),
builder: (context,
AsyncSnapshot<
QuerySnapshot<Map<String, dynamic>>>
snapshot) {
if (!snapshot.hasData) {
setState(() {
_isLoading = false;
});
return Container();
}
if (snapshot.hasError) {
setState(() {
_isLoading = false;
});
}
List<DocumentSnapshot> itemsList = [];
for (DocumentSnapshot doc
in snapshot.data!.docs) {
if (doc['restaurantId'] ==
Utils.restaurant!.restaurantId &&
doc['orderStatus'] == "In Progress") {
itemsList.add(doc);
}
}
return buildRestaurantCards("Current Orders",
Icons.list_alt, itemsList.length);
},
)
: buildRestaurantCards(
"Current Orders", Icons.list_alt, 0),
buildRestaurantCards("Order History", Icons.history, 0),
],
),
),
Container(
height: MediaQuery.of(context).size.height * 0.25,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildRestaurantCards(
"Menu\nManagement", Icons.restaurant_menu_rounded, 0),
buildRestaurantCards("Update Profile", Icons.person, 0),
],
),
),
],
),
)
);
}
}
Check if there are any exceptions caught in the debug console, If there are then fix those, then the issue will be resolved

Snapshot from StreamBuilder

I am working on a ListView inside a Streambuilder with data from Cloud Firestore.
Here you have the code:
//inicio stream
StreamBuilder<List<Evento>>(
stream: eventosProvider
.eventosbares,
builder: (context, snapshot) {
if (snapshot
.data.isNotEmpty) {
return SizedBox(
height: 155,
child: ListView.builder(
scrollDirection:
Axis.horizontal,
itemCount: snapshot
.data.length,
itemBuilder:
(context,
index) {
var dateString =
snapshot
.data[
index]
.fechaEvento;
var date = DateFormat(
'd-M-yyyy HH:mm',
'de_DE')
.parse(
dateString);
return Card(
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
10),
),
child:
Container(
height: 178,
width: 280,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 8.0,
right: 8.0,
top: 8.0),
child:
ClipRRect(
borderRadius:
BorderRadius.circular(8),
child:
Image.network(
snapshot.data[index].imagenEvento,
width: 278.0,
height: 80.0,
fit: BoxFit.fill,
),
),
),
Padding(
padding:
const EdgeInsets.all(8.0),
child:
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
CircleAvatar(
radius: 20.0,
backgroundImage: NetworkImage(snapshot.data[index].fotoPerfilAutor),
backgroundColor: Colors.transparent,
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: 150,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
snapshot.data[index].tituloEvento,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
Text(
DateFormat('EEEEE dd MMM yyyy HH:mm', 'es_ES').format(date),
style: TextStyle(fontSize: 10),
),
],
),
),
),
SizedBox(
width: 10,
),
Text(
snapshot.data[index].num_invitados,
style: TextStyle(color: ColoresApp.naranjaTop, fontWeight: FontWeight.bold, fontSize: 14),
),
SizedBox(
width: 5,
),
CircleAvatar(
radius: 10.0,
backgroundImage: AssetImage("assets/friends.png"),
backgroundColor: Colors.transparent,
)
],
),
),
]),
),
);
}),
);
} else {
return Text(
"No hay eventos en bares",
style: TextStyle(
color:
Colors.white),
);
}
}),
I am getting the following exception using this code, the app is not exiting, it only shows a red error background for a moment, but it is not acceptable:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building StreamBuilder<List<Evento>>(dirty, state: _StreamBuilderBaseState<List<Evento>, AsyncSnapshot<List<Evento>>>#d6fd3):
The getter 'isNotEmpty' was called on null.
Receiver: null
Tried calling: isNotEmpty
I have tried changing the line:
if (snapshot.data.isNotEmpty)
with
if (snaphot.hasData)
but then, the exception is gone, but there is a blank space thrown, not the else part of the if clause.
What should I do to know if the snapshop has really data or is waiting to get them?
EDIT
Here you have the service loading the Stream:
Stream<List<Evento>> getEventosBares(){
return _db
.collection('eventos').where('interes', isEqualTo: 'bares')
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Evento.fromJson(doc.data()))
.toList());
}
And here you have the provider:
Stream<List<Evento>> get eventosbares => firestoreService.getEventosBares();
Try adding a null check:
builder: (context, snapshot) {
if (snapshot.data != null && snapshot.data.isNotEmpty) {
return SizedBox(...);

Why does my application close when I use a listview with Cards and NetworkImage?

The ListView.builder is being built with some cards that contain NetworkImage, for the moment it creates 25 cards for me, therefore it has to load 25 images, at the moment of making a slide the application remains stopped and at the end it closes, which could be doing wrong? Here is the code, I would appreciate if you could help me. Images are stored in Firebase Storage and weigh less than 300 kb,
It is also worth mentioning that when I scroll through the listview the images are reloaded.
FutureBuilder(
future: urlPublicaciones.cargarUrlPublicaciones(),
builder: (BuildContext context,
AsyncSnapshot<List<UrlPublicacionesModel>> snapshotUrl) {
if (snapshotUrl.hasData) {
urlPosts = snapshotUrl.data;
return FutureBuilder(
future: urlPublicaciones.cargarPublicaciones(urlPosts),
builder: (BuildContext context,
AsyncSnapshot<List<CategoriasResponse>> snapshot) {
if (snapshot.hasData) {
publicaciones = snapshot.data;
if (publicaciones.isNotEmpty) {
return ListView.builder(
itemCount: publicaciones.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
confirmDismiss: (direction) async {
switch (direction) {
case DismissDirection.endToStart:
return await _showConfirmationDialog(
context) ==
true;
case DismissDirection.startToEnd:
return await _showConfirmationDialog(
context) ==
true;
case DismissDirection.horizontal:
case DismissDirection.vertical:
case DismissDirection.up:
case DismissDirection.down:
assert(false);
}
return false;
},
background: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerLeft,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
secondaryBackground: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerRight,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
key: UniqueKey(),
onDismissed: (direction) async {
_showCircularProgressDelete(context);
if (await urlPublicaciones
.eliminarPublicacion(urlPosts[index])) {
setState(() {
publicaciones.removeAt(index);
});
Navigator.pop(context);
}
else {
Navigator.pop(context);
await _showErrorDialog(context);
}
},
child: _tarjeta(
context, publicaciones[index], index));
},
);
} else {
return Center(
child: Text(
'Aún no cuentas con ninguna publicación',
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center));
}
} else {
return Center(child: CircularProgressIndicator());
}
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
Widget _tarjeta(
BuildContext context,
CategoriasResponse publicacion, int index) {
colores = _calculoPuntuacion(publicacion.calificacion.calificacion_total);
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 10),
child: GestureDetector(
onTap: () {
Navigator.pushNamed(context, 'detalle_mipublicacion',
arguments: publicacion);
},
child: Card(
elevation: 10.0,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
child: Column(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 10.0,
),
Container(
padding:
EdgeInsetsDirectional.fromSTEB(5.0, 10.0, 10.0, 0.0),
alignment: AlignmentDirectional.center,
child: _cargarImagen(publicacion)),
Column(
children: <Widget>[
SizedBox(
height: 28.0,
child: Text(
publicacion.nombre,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
textAlign: TextAlign.center,
)),
Text(
'Categoria: ' + publicacion.categoria,
style: TextStyle(
fontWeight: FontWeight.normal, fontSize: 15.0),
textAlign: TextAlign.center,
)
],
),
],
),
Column(
children: <Widget>[
SizedBox(
height: 35.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star, color: colores[0]),
Icon(Icons.star, color: colores[1]),
Icon(Icons.star, color: colores[2]),
Icon(Icons.star, color: colores[3]),
Icon(Icons.star, color: colores[4]),
Text(publicacion.calificacion.calificacion_total
.toString())
],
),
)
],
),
Column(
children: <Widget>[
Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.phone, color: Colors.orangeAccent),
Text(publicacion.telefono.toString(),
overflow: TextOverflow.ellipsis)
],
),
]),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.location_on,
color: Colors.orangeAccent),
Text(publicacion.direccion,
overflow: TextOverflow.ellipsis)
],
),
]),
],
),
],
),
SizedBox(height: 10)
],
),
),
),
);
}
Widget _cargarImagen(CategoriasResponse publicacion) {
final logo = Container(
child: Card(
elevation: 5.0,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: FadeInImage(
placeholder: AssetImage('assets/img/giphy.gif'),
image: NetworkImage(publicacion.fotos.url1),
height: 150.0,
width: 170.0,
fit: BoxFit.fill),
),
),
);
return logo;
}
Try this:
FutureBuilder(
future: urlPublicaciones.cargarUrlPublicaciones(),
builder: (BuildContext context,
AsyncSnapshot<List<UrlPublicacionesModel>> snapshotUrl) {
if (snapshotUrl.hasData) {
urlPosts = snapshotUrl.data;
return FutureBuilder(
future: urlPublicaciones.cargarPublicaciones(urlPosts),
builder: (BuildContext context,
AsyncSnapshot<List<CategoriasResponse>> snapshot) {
if (snapshot.hasData) {
publicaciones = snapshot.data;
if (publicaciones.isNotEmpty) {
return ListView.builder(
itemCount: publicaciones.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
confirmDismiss: (direction) async {
switch (direction) {
case DismissDirection.endToStart:
return await _showConfirmationDialog(
context);
case DismissDirection.startToEnd:
return await _showConfirmationDialog(
context);
}
},
background: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerLeft,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
secondaryBackground: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerRight,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
key: UniqueKey(),
onDismissed: (direction) async {
_showCircularProgressDelete(context);
if (await urlPublicaciones
.eliminarPublicacion(urlPosts[index])) {
setState(() {
publicaciones.removeAt(index);
});
Navigator.pop(context);
}
else {
Navigator.pop(context);
await _showErrorDialog(context);
}
},
child: _tarjeta(
context, publicaciones[index], index));
},
);
} else {
return Center(
child: Text(
'Aún no cuentas con ninguna publicación',
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center));
}
} else {
return Center(child: CircularProgressIndicator());
}
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),

Flutter: How to merge two StreamBuilder and show the output in a card

I'm kinda stuck with what I'm trying to do. I'm trying to merge my two Stream Builder to show the output as one in a card. In my first StreamBuilder thats where I'm getting some infos of the user like the info that he posted, what they need like that. And in my 2nd StreamBuilder thats where I get his/her name, contacts like that. Is it possible to merge it as one? so I'll get the data as one also.
This is how I use my StreamBuilders.
1st stream:
StreamBuilder<QuerySnapshot>(
stream: db.collection('HELP REQUEST').where('Type_OfDisaster', isEqualTo: '[Drought]').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList()
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator()
)
);
}
}
);
2nd Stream:
StreamBuilder<QuerySnapshot>(
stream: db.collection('USERS').where('User_ID', isEqualTo: widget.Uid).snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList()
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator()
)
);
}
}
);
Here is where I output the data I get in the stream builder:
Container buildItem(DocumentSnapshot doc) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
return Container(
child: Card(
elevation: 5,
child: Padding(
padding: const EdgeInsets.only(top: 20, left: 20, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(
radius: 30,
backgroundColor: Colors.black,
),
SizedBox(
width: 10,
),
Text('Name: '),
Text(
'${doc.data['Name_ofUser']}',
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w500),
)
],
),
],
),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 20,
),
Row(
children: <Widget>[
Text('Date:'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${doc.data['Help_DatePosted']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w500),
),
),
],
),
Row(
children: <Widget>[
Text('Location:'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${doc.data['Help_Location']}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w500),
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text('Description:'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${doc.data['Help_Description']}',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w500),
),
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
height: _height * 0.05,
width: _width * 0.20,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20.0))),
color: Color(0xFF121A21),
onPressed: () {
_viewingRequest(doc.data);
},
child: Text(
'View',
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w800),
),
),
),
)
],
),
],
),
),
),
);
}
Is it possible to do it? Please help me.
You can listen to the snapshots without using a StreamBuilder directly, like this:
List<HelpRequestsPlusUsers> helpRequestsPlusUsers = [];
List<User> allUsers = [];
List<HelpRequest> helpRequests = [];
#override
void initState() {
db.collection('USERS').where('User_ID', isEqualTo: widget.Uid).snapshots().listen((snapshot){
allusers = snapshot.data.documents;
mergeUsersWithHelpRequests();
});
db.collection('HELP REQUEST').where('Type_OfDisaster', isEqualTo: '[Drought]').snapshots().listen((snapshot){
helpRequests = snapshot.data.documents;
mergeUsersWithHelpRequests();
});
super.initState();
}
void mergeUsersWithHelpRequests(){
// Run the code to merge your allUsers and helpRequests data into a helpRequestsPlusUsers List
}
Widget
Widget _buildHelpRequestsPlusUsersWidget (){
if (helpRequestsPlusUsers.isNotEmpty) {
return ListView.builder(
itemBuilder: (context, index){
return buildItem(helpRequestsPlusUsers[index]);
}
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator()
)
);
}
}