How to fix 'Methode called on null in a streambuilder' - flutter

I'm trying to fetch data from firestore but I keep getting methode called on null error
I want it to keep showing circular progress indicator in case of an error or slow connection
class FirstTabPage extends StatelessWidget {
final CustomCard customCard = CustomCard();
#override
Widget build(BuildContext context) {
return
Padding(
padding: const EdgeInsets.all(8.0),
child: StreamBuilder(
stream: Firestore.instance.document('data/Sqprices').snapshots(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator(backgroundColor: Colors.black,),);
} else {
return ListView(
children: <Widget>[
CustomCard(
image: Image.asset('images/elag.png',width: 40,height: 40,),
currencyName: 'EUR',
buyPrice: '${snapshot.data['price1']}',
sellPrice: '${snapshot.data['price2']}',
),
CustomCard(
image: Image.asset('images/ulag.png',width: 40,height: 40,),
currencyName: 'USD',
buyPrice: '${snapshot.data['price3']}',
sellPrice: '${snapshot.data['price4']}',
),
CustomCard(
image: Image.asset('images/klag.png',width: 40,height: 40,),
currencyName: 'GBP',
buyPrice: '${snapshot.data['price5']}',
sellPrice: '${snapshot.data['price6']}',
),
],
);
}
}
),
);
}
}
When there is internet acces the progress indicator shows for 2 seconds and then the data get displayed , but in slow internet acces it crashes saying the
the methode [] was called on null

Try with this,
builder: (context, AsyncSnapshot snapshot){
......
.....
....
}

You have checked for .hasData which ensures that data should be available in the Stream. However, the data in the Stream can also be null data. So, you should check if data equals null:
child: StreamBuilder(
stream: Firestore.instance.document('data/Sqprices').snapshots(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator(backgroundColor: Colors.black,),);
}
if(snapshot.data == null) return Center(child: Text("No data"));
else {
return ListView(

Related

Text position problems with UserAccountsDrawerHeader in the Drawer in flutter

I am using a userAccountsDrawerHeader in the Drawer with a photo, username and email but I get a location or text positioning problem.
The text it shows is from the database using a future builder and it gives me a problem.
But when I test the properties of userAccountsDrawerHeader(accountName,accountEmail) using a Text widget with no data from the database, the text is located correctly, no problem there.
How can I solve that?
Your help would be greatly appreciated.
code and image::
UserAccountsDrawerHeader(
accountName:NombreCabeceraDrawer(),
accountEmail:CorreoCabeceraDrawer(),
),
class CorreoCabeceraDrawerextends StatefulWidget{return correocabeceradrawer ();}
class correocabeceradrawer extends State<CorreoCabeceraDrawer>{
Widget CorreoCabeceraDrawer(){
return Container(
child: Text(correousuario), ); }
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: futureServices,
builder:(context, AsyncSnapshot snapshot) {
List listainfocabeceradrawer = snapshot.data;
if(snapshot.hasData ) {
return Center(
child: Container(
child: ListView.builder(
itemCount: listainfocabeceradrawer.length,
itemBuilder: (context,i){
correousuario = listainfocabeceradrawer[i].CorreoUsuario;
return Container(
child: CorreoCabeceraDrawer(),
); }), ),);
}else if(snapshot.hasError){
return Text("${snapshot.error}");
} return Center(
child: CircularProgressIndicator()
);
}
),
);
throw UnimplementedError();
}}
enter image description here
enter image description here
enter image description here
if we think simple is this code work with your code?
UserAccountsDrawerHeader(
accountName:NombreCabeceraDrawer(),
accountEmail:CorreoCabeceraDrawer(),
),
class CorreoCabeceraDrawerextends StatefulWidget{return correocabeceradrawer ();}
class correocabeceradrawer extends State<CorreoCabeceraDrawer>{
Widget CorreoCabeceraDrawer(){
return Container(margin:EdgeInsets.only(top:40),
child: Text(correousuario), ); }
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: futureServices,
builder:(context, AsyncSnapshot snapshot) {
List listainfocabeceradrawer = snapshot.data;
if(snapshot.hasData ) {
return Center(
child: Container(
child: ListView.builder(
itemCount: listainfocabeceradrawer.length,
itemBuilder: (context,i){
correousuario = listainfocabeceradrawer[i].CorreoUsuario;
return Container(
child: CorreoCabeceraDrawer(),
); }), ),);
}else if(snapshot.hasError){
return Text("${snapshot.error}");
} return Center(
child: CircularProgressIndicator()
);
}
),
);
throw UnimplementedError();
}}

Null check operator used on a null value in a stream builder, flutter

im getting this exception when i load the page, it appear on display for a moment but when list is loaded it disappears. errors reads out line 255, att line 255 i have a child: streambuilder
i cannot figure out whats wrong
Expanded(
child: StreamBuilder(
stream: restaurants.where('status', isEqualTo: 'Approved').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data!.docs.map((restaurants) {
return RestaurantCard(restaurants: restaurants,);
}).toList(),
);
},
),
)
You have to check for different statuses in StreamBuilder, and only build the ListView if there is data available:
StreamBuilder<DocumentSnapshot>(
stream: restaurants.where('status', isEqualTo: 'Approved').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return const Center(
child: Text('Snapshot error'),
);
}
if (!snapshot.hasData) {
return const Center(
child: Text('Snapshot data missing'),
);
}
return ListView(
children: snapshot.data!.docs.map((restaurants) {
return RestaurantCard(restaurants: restaurants,);
}).toList(),
);
})

How to extract snapshot data and save as a global variable in flutter

I don't know whether this is a dumb question or not. Pardon me if it is.
I created a streamBuilder and now I want to extract it's AsyncSnapshot and save as a global variable. Currently I only have access to that snapshot is, inside the streamBuilder widget. But I want that snapshot data to update some widgets outside that streamBuilder widget. I have added a comment to below code:
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: _crudStorage.all(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.waiting:
if (snapshot.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
final tasksList = snapshot.data as List<Task>; //I want to extract this
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
tasksList.isEmpty
? const RiveBird()
: Expanded(
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: tasksList.length + 1,
itemBuilder: (context, index) {
if (index == tasksList.length) {
return const SizedBox(
height: 85.0,
width: double.infinity,
);
}
final task = tasksList[index];
return Dismissible();
},
),
),
],
);
default:
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}

Stream Builder Returning Null Value in flutter although Data is present in cloud firestore document

I need help with one case in which my stream builder is returning null values.
I am trying to retrieve a list of services stored in cloud firestore and will display using listview builder later. For now trying to see in the container widget.
I am attaching a snap from my cloud firestore data.
Thanks in Advance.
Here is my code,
return Scaffold(
key: _globalKey,
body: Padding(
padding: EdgeInsets.only(left: 20, top: 50, right: 20),
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('city')
.doc(Pune)
.collection(Pashan)
.doc('merchantData')
.collection('merchantInfo')
.where('categoryType', isEqualTo: 'Services')
.orderBy('storeType', descending: true)
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
print(snapshot.data);
if (snapshot.data != null) {
_storeTypes.clear();
for (var num in snapshot.data.docs) {[enter image description here][1]
if (!_storeTypes.contains(num['storeType'])) {
_storeTypes.add(
num['storeType'],
);
}
}
}
return ListView.builder(
itemCount: _storeTypes.length,
itemBuilder: (context, index) {
return Container(
child: Center(
child: Text(_storeTypes[index]),
),
);
},
);
},
),
),
it's because your trying to use the data before it's fetching from firebase so to avoid the above error add the below code above your if conditions .If you find this answer is correct up vote this answer
if (snapshot.hasError) {
return Center(
child: Text("Something went wrong"),
);
}
if (!snapshot.hasData) {
return Center(
child: Text("No notice found"),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}

How do I solve type 'MappedListIterable<DocumentSnapshot, dynamic>' is not a subtype of type 'List<Widget>' errors

I'm using FutureBuilder to Query Firestore for the documentID in one collection then pass the documentID to another collection.The relevant error-causing widget wasFutureBuilder
What could be the issue? I've checked the code I'm not sure maybe its the format.
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
The first Future builder retrieves the documentID in Cart
FutureBuilder( // <<=========FutureBuilder
future: usersref
.document().
collection("Cart")
.getDocuments(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
CircularProgressIndicator();
}
{
return ListView( // <<=== ListView
padding: EdgeInsets.only(
top: 108.0,
bottom: 12.0,
),
children: snapshot
.data.
documents.map((document) { // <<===snapshot map
return FutureBuilder(
future: productsRef
.document(widget.shopname)
.collection("products")
Then It's passed below to another collection reference
.document(document.documentID) //<<===documentID
.get(),
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
Center(
child: Text("Waiting...'"),
);
}
if (snapshot.connectionState == ConnectionState.done) {
Map _productMap = document.data.documents(); // <<<======== Map
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: 90,
height: 90,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
From the collection reference, Im querying the data.
child: Image.network(
"${_productMap['images'][0]}",
fit: BoxFit.cover,
),
),
),
],
);
}},
);
}),
);
}
})
],
));
}
}
So i see multiple things that can go wrong. I'm not sure why you're nesting multiple FutureBuilders in a parent FutureBuilder. Scaffold should be on top level, now you have multiple of them.
The error you get is in the ListViews children. It expects widgets but you're mapping it to another FutureBuilder.
snapshot.data.documents.map((document) {
return FutureBuilder(
future: productsRef
.document(widget.shopname)
.collection("products").document(document.documentID)
.get(),
the snapshot has all the info you need so try this:
ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (ctx, i) => Text(snapshot.data.documents[i].documentID) // <-docID
Also, i generally use futurebuilder to check the state of the user, to get the documents, use StreamBuilder