StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>): - flutter

I cant able to retrive the data from Firestore and getting Error as below,
════════ Exception caught by widgets library
═══════════════════════════════════════════════════════ The following
assertion was thrown building StreamBuilder(dirty,
state: _StreamBuilderBaseState<QuerySnapshot,
AsyncSnapshot>#e568b): A build function returned null.
The offending widget is: StreamBuilder Build functions
must never return null.
To return an empty space that causes the building widget to fill
available room, return "Container()". To return an empty space that
takes as little room as possible, return "Container(width: 0.0,
height: 0.0)".
The relevant error-causing widget was: StreamBuilder
file:...dart:140:15 When the exception was thrown, this was the stack:
#0 debugWidgetBuilderValue. (package:flutter/src/widgets/debug.dart:300:7)
#1 _Closure.call (dart:core-patch/function.dart)
#2 debugWidgetBuilderValue (package:flutter/src/widgets/debug.dart:321:4)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4569:7)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4737:11) ...
Below is my code.
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("currency").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData){
print('test pharse');
Text("Loading.....");}
else {
List<DropdownMenuItem> currencyItems = [];
for (int i = 0; i < snapshot.data.documents.length; i++) {
DocumentSnapshot snap = snapshot.data.documents[i];
currencyItems.add(
DropdownMenuItem(
child: Text(
snap.documentID,
style: TextStyle(color: Color(0xff11b719)),
),
value: "${snap.documentID}",
),
);
}
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.mail,
size: 25.0, color: Color(0xff11b719)),
SizedBox(width: 50.0),
DropdownButton(
items: currencyItems,
onChanged: (currencyValue) {
final snackBar = SnackBar(
content: Text(
'Selected Currency value is $currencyValue',
style: TextStyle(color: Color(0xff11b719)),
),
);
Scaffold.of(context).showSnackBar(snackBar);
setState(() {
selectedCurrency = currencyValue;
});
},
value: selectedCurrency,
isExpanded: false,
hint: new Text(
"Choose Currency Type",
style: TextStyle(color: Color(0xff11b719)),
),
),
],
);
}
}),

You need to add a return before the Text widget in the !snapshot.hasData section of the StreamBuilder
if (!snapshot.hasData){
print('test phrase');
return Text("Loading.....");
}

Related

Unhandled Exception: type '_DropdownRouteResult<int>' is not a subtype of type 'int?' when returning value from Navigator.pop()

In a DropdownButtonFormField, I have a list of standard DropdownMenuItems populated from a Provider and an "Add New" button which pushes a MaterialRoute containing a Form. When submitted, the form asynchronously inserts the new data to the db via the Provider and returns the db id in the call to Navigator.pop().
The intended behaviour is that the pop() callback should set the value of the dropdown field to the returned int value, and the dropdown menu should be closed, with the updated value reflected.
In the code snippet below, I have two versions of this "Add New" DropdownMenuItem. The "working" version performs as expected, but doesn't close the dropdown menu when pressed (also as expected, given that it's a button and not a normal dropdown element).
The "broken" version fails to push the new route, and throws
E/flutter (24895): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type '_DropdownRouteResult<int>' is not a subtype of type 'int?'
E/flutter (24895): #0 _TeaProducerFormFieldState.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:teavault/screens/stash/teaform.dart:70:15)
E/flutter (24895): #1 State.setState (package:flutter/src/widgets/framework.dart:1109:30)
E/flutter (24895): #2 _TeaProducerFormFieldState.build.<anonymous closure>.<anonymous closure> (package:teavault/screens/stash/teaform.dart:69:13)
E/flutter (24895): #3 _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter (24895): #4 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
L70 referred to here is _selectedValue = value;. The behaviour occurs whether I use async/await or .then() syntax.
I can't tell whether this is due to a pre-emptive type check or a weird failure to wait for the Promise due to something I'm missing.
Relevant code is as follows:
class _TeaProducerFormFieldState extends State<TeaProducerFormField> {
int? _selectedValue;
#override
Widget build(BuildContext context) {
final teaProducers = Provider.of<TeaProducerCollectionModel>(context).items;
final teaProducerListItems = teaProducers.map((producer) => DropdownMenuItem<int>(
value: producer.id,
child: Text(producer.name),
)).toList();
final workingAddNewTeaProducerButton = DropdownMenuItem<int>(child: TextButton(
onPressed: () async {
final int newValue = await Navigator.push(context, AddNewTeaProducerRoute());
setState(() {
_selectedValue = newValue;
});
},
child: Text('Add New Manufacturer')));
final brokenAddNewTeaProducerButtion = DropdownMenuItem<int>(
onTap: () {
Navigator.push(context, AddNewTeaProducerRoute()).then((value) {
setState(() {
_selectedValue = value;
});
});
},
value: 0,
child: const Text('Add New Manufacturer'));
return DropdownButtonFormField(
value: _selectedValue,
items: teaProducerListItems + [brokenAddNewTeaProducerButtion],
// child: addNewTeaProducerButton)],
onChanged: (_) {},
hint: Text('Select a manufacturer'),
);
}
}
EDIT:
After modifying per #Axel's suggestion and pulling in the subtree content directly for clarity, I have the following, but still receive
When the exception was thrown, this was the stack:
#0 LocalHistoryRoute.didPop (package:flutter/src/widgets/routes.dart)
#1 _RouteEntry.handlePop (package:flutter/src/widgets/navigator.dart:2896:16)
#2 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3868:22)
#3 NavigatorState.pop (package:flutter/src/widgets/navigator.dart:4910:7)
#4 Navigator.pop (package:flutter/src/widgets/navigator.dart:2432:27)
#5 _DropdownMenuItemButtonState._handleOnTap (package:flutter/src/material/dropdown.dart:148:15)
I thought to add an int? type arg to the relevant MaterialPageRoute, but received the same result.
final brokenAddNewTeaProducerButton = DropdownMenuItem<int>(
onTap: () {
Navigator.push<int?>(context, MaterialPageRoute(
builder: (BuildContext context) =>
Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.white),
title: Text('Define new Manufacturer'),
),
body: Column(
children: <Widget>[
Expanded(
flex: MediaQuery.of(context).orientation == Orientation.portrait ? 4 : 1,
child: Container(),
),
Expanded(
flex: 16,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 50.0),
child: const TeaProducerForm(),
),
),
],
)
))).then((value) {
setState(() {
_selectedValue = value;
});
});
},
value: 0,
child: const Text('Add New Manufacturer'));
//[...]
class TeaProducerFormState extends State<TeaProducerForm> {
final _formKey = GlobalKey<FormState>();
String? fullName;
String? shortName;
#override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
onSaved: ((value) {fullName = value;}),
decoration: const InputDecoration(
hintText: 'Enter full name',
labelText: 'Full Name'
),
),
TextFormField(
onSaved: ((value) {shortName = value;}),
decoration: const InputDecoration(
hintText: 'Enter abbreviated name',
labelText: 'Short Name'
),
validator: ((value) {
if ((value ?? '').length > 6 ) {
return 'Please enter a name with six or fewer characters';
} else if ((value ?? '').isEmpty ) {
return 'Please enter a name with one or more characters';
}
}),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState?.validate() ?? false) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Saving new manufacturer...')),);
_formKey.currentState?.save();
final teaProducers = Provider.of<TeaProducerCollectionModel>(context, listen: false);
teaProducers.insert(TeaProducer(
name: fullName!,
shortName: shortName!
)).then((value) {
print('added tea as id $value');
ScaffoldMessenger.of(context).clearSnackBars();
Navigator.pop<int?>(context, value);
});
}
},
child: const Text('Submit'))
// Add TextFormFields and ElevatedButton here.
],
),
);
}
}
Try specify the type you expect in return from Navigator.push and the type you want to return when you Navigator.pop inside of AddNewTeaProducerRoute.
Your code should look like:
final brokenAddNewTeaProducerButtion = DropdownMenuItem<int>(
onTap: () {
Navigator.push<int?>(context, AddNewTeaProducerRoute()).then((value) {
setState(() {
_selectedValue = value;
});
});
},
value: 0,
child: const Text('Add New Manufacturer'));
And inside of AddNewTeaProducerRoute, do:
Navigator.pop<int?>(context, value);
You shouldn't get any cast exceptions after this.

cannot dismiss Flushbar on button tap (Flushbar is a package for Flutter)

According to the documentation it shall work like this:
flush = Flushbar<List<String>>(
userInputForm = Form(
key: _formKey,
child: Column(
children: [
getTextFormField("Initial Value"),
]
MaterialButton(
child: Text("SUBMIT"),
onPressed: () {
flush.dismiss([_controller1.value.text]);
},
),
],),),
)..show(context).then((result) {
if (result != null) {
String userInput1 = result[0];
}
});
Not sure, how this example is embedded in the surrounding code. In my case, I have a separate file with the different flushbars. I call them by
CupertinoButton(
onPressed: () => flush = newArea(context, _formKey, flush),
child: Text('add')
),
My initial attempt did not work and since in my set-up flush.dismiss did not work, because I was lacking flush in the context of my "stand-alone-flush-function", I added the argument Flushbar<List<String>> flush; to the function call, but that didn't help either.
The error shown is: (and it vanishes as soon as I make the dismiss line a comment)
======== Exception caught by gesture library =======================================================
The following RangeError was thrown while dispatching a pointer event:
RangeError (index): Invalid value: Only valid value is 0: 1
When the exception was thrown, this was the stack:
#0 List.[] (dart:core-patch/growable_array.dart:177:60)
#1 StackFrame.fromStackTraceLine (package:flutter/src/foundation/stack_frame.dart:214:36)
#2 MappedIterator.moveNext (dart:_internal/iterable.dart:392:20)
#3 WhereTypeIterator.moveNext (dart:_internal/iterable.dart:875:20)
#4 new List.from (dart:core-patch/array_patch.dart:50:19)
My Flush function looks like this:
Flushbar<List<String>> newArea(BuildContext context,
GlobalKey _formKey, Flushbar flush) {
ProjectKanbanBloc kanbanBloc = BlocProvider.of<ProjectKanbanBloc>(context);
TextEditingController inputTec = TextEditingController();
String areaName;
return Flushbar(
userInputForm: Form(
key: _formKey,
child: Expanded(
child: StatefulBuilder(
builder: (BuildContext contextFlush, StateSetter setState) {
return Column(
children: <Widget>[
child: CupertinoTextField(
controller: inputTec,
onSubmitted: (val) {
setState(() {
areaName = val;
});
},
)),
CupertinoButton(
child: Text('save'),
onPressed: () {
BlocProvider.of<ProjectKanbanBloc>(context).add(
ProjectKanbanAreaAdded(areaName: inputTec.text));
flush.dismiss(); // <<<<<<<<<<<<<<<<-------------- DISMISS
},
)
]);
})),
))..show(context);
}
Got it! You can simply use Navigator.pop(context); within onPressed:

Flutter: type 'Future<dynamic>' is not a subtype of type 'Widget' // MaterialPageRoute<dynamic>(null))

I am trying to navigate to the camera screen and when I trigger the navigation, I get the error
Another exception was thrown: type 'Future<dynamic>' is not a subtype of type 'Widget'
Another exception was thrown: setState() or markNeedsBuild() called during build.
The error points to the navigation from previous page I came from.
I also saw this error in there too
The AnimationController notifying status listeners was: AnimationController#a911e(⏮ 0.000; paused; for MaterialPageRoute<dynamic>(null))
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CameraScreen())),
This is the function that gets the error
captureImageWithCamera() async {
Navigator.pop(this.context);
File imageFile = await ImagePicker.pickImage(
source: ImageSource.camera,
maxHeight: 680,
maxWidth: 970,
);
if (imageFile != null) {
//imageFile = await cropImage(imageFile);
setState(() {
//this.file = imageFile as File;
print(file);
});
await controller.dispose();
}
}
Just for full context, here's the full builder from the first page that calls the navigation to the camera screen. You'll see the navigation to the CameraScreen in there.
createStoryView() {
return FutureBuilder(
future: usersReference.document(currentOnlineUserId).get(),
builder: (context, dataSnapshot) {
if (!dataSnapshot.hasData) {
return circularProgress();
} else {
User user = User.fromDocument(dataSnapshot.data);
return Material(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(0.0),
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
leading: Stack(
children: <Widget>[
GestureDetector(
child: Padding(
padding: EdgeInsets.only(top: 0.0, bottom: 0.0),
child: user.photoUrl.isNotEmpty
? CircleAvatar(
radius: 30.0,
backgroundColor: Colors.grey,
backgroundImage:
CachedNetworkImageProvider(
user.photoUrl),
)
: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.grey,
),
),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StoryPageView())),
),
],
),
title: Text(
user.profileName,
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text("Add a Story"),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CameraScreen())),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Viewed Stories",
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.bold,
),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(0.0),
color: Colors.white,
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
leading: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.grey,
),
title: Text(
"Username",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text("Timestamp"),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StoryPageView())),
),
),
],
),
),
),
],
),
);
}
},
);
}
Here is the builder for the CameraPage
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue),
title: Text(
"Story Post",
style: TextStyle(
color: Colors.blue,
fontSize: 22.0,
),
),
),
body: file == null ? captureImageWithCamera() : displayStoryUploadScreen(),
);
}
Here's the full error message
══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞═════════════════════════════════════════════════════════
The following assertion was thrown while notifying status listeners for AnimationController:
setState() or markNeedsBuild() called during build.
This _ModalScope<dynamic> 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.
The widget on which setState() or markNeedsBuild() was called was:
_ModalScope<dynamic>-[LabeledGlobalKey<_ModalScopeState<dynamic>>#0c8ee]
The widget which was currently being built when the offending call was made was:
CameraScreen
When the exception was thrown, this was the stack:
[38;5;244m#0 Element.markNeedsBuild.<anonymous closure>[39;49m
[38;5;244m#1 Element.markNeedsBuild[39;49m
[38;5;244m#2 State.setState[39;49m
[38;5;244m#3 _ModalScopeState._routeSetState[39;49m
[38;5;244m#4 ModalRoute.setState[39;49m
[38;5;244m#5 ModalRoute.changedInternalState[39;49m
[38;5;244m#6 TransitionRoute._handleStatusChanged[39;49m
[38;5;244m#7 AnimationLocalStatusListenersMixin.notifyStatusListeners[39;49m
[38;5;244m#8 AnimationController._checkStatusChanged[39;49m
[38;5;244m#9 AnimationController._animateToInternal[39;49m
[38;5;244m#10 AnimationController.reverse[39;49m
[38;5;244m#11 TransitionRoute.didPop[39;49m
[38;5;244m#12 LocalHistoryRoute.didPop[39;49m
[38;5;244m#13 _RouteEntry.pop[39;49m
[38;5;244m#14 NavigatorState.pop[39;49m
[38;5;244m#15 Navigator.pop[39;49m
[38;5;248m#16 _CameraScreenState.captureImageWithCamera[39;49m
[38;5;248m#17 _CameraScreenState.build[39;49m
[38;5;244m#18 StatefulElement.build[39;49m
[38;5;244m#19 ComponentElement.performRebuild[39;49m
[38;5;244m#20 StatefulElement.performRebuild[39;49m
[38;5;244m#21 Element.rebuild[39;49m
[38;5;244m#22 ComponentElement._firstBuild[39;49m
[38;5;244m#23 StatefulElement._firstBuild[39;49m
[38;5;244m#24 ComponentElement.mount[39;49m
... Normal element mounting (24 frames)
[38;5;244m#48 Element.inflateWidget[39;49m
[38;5;244m#49 MultiChildRenderObjectElement.mount[39;49m
... Normal element mounting (136 frames)
[38;5;244m#185 Element.inflateWidget[39;49m
[38;5;244m#186 Element.updateChild[39;49m
[38;5;244m#187 RenderObjectElement.updateChildren[39;49m
[38;5;244m#188 MultiChildRenderObjectElement.update[39;49m
[38;5;244m#189 Element.updateChild[39;49m
[38;5;244m#190 ComponentElement.performRebuild[39;49m
[38;5;244m#191 StatefulElement.performRebuild[39;49m
[38;5;244m#192 Element.rebuild[39;49m
[38;5;244m#193 StatefulElement.update[39;49m
[38;5;244m#194 Element.updateChild[39;49m
[38;5;244m#195 ComponentElement.performRebuild[39;49m
[38;5;244m#196 Element.rebuild[39;49m
[38;5;244m#197 ProxyElement.update[39;49m
[38;5;244m#198 _InheritedNotifierElement.update[39;49m
[38;5;244m#199 Element.updateChild[39;49m
[38;5;244m#200 SingleChildRenderObjectElement.update[39;49m
[38;5;244m#201 Element.updateChild[39;49m
[38;5;244m#202 ComponentElement.performRebuild[39;49m
[38;5;244m#203 StatefulElement.performRebuild[39;49m
[38;5;244m#204 Element.rebuild[39;49m
[38;5;244m#205 StatefulElement.update[39;49m
[38;5;244m#206 Element.updateChild[39;49m
[38;5;244m#207 SingleChildRenderObjectElement.update[39;49m
[38;5;244m#208 Element.updateChild[39;49m
[38;5;244m#209 SingleChildRenderObjectElement.update[39;49m
[38;5;244m#210 Element.updateChild[39;49m
[38;5;244m#211 ComponentElement.performRebuild[39;49m
[38;5;244m#212 Element.rebuild[39;49m
[38;5;244m#213 StatelessElement.update[39;49m
[38;5;244m#214 Element.updateChild[39;49m
[38;5;244m#215 ComponentElement.performRebuild[39;49m
[38;5;244m#216 Element.rebuild[39;49m
[38;5;244m#217 ProxyElement.update[39;49m
[38;5;244m#218 Element.updateChild[39;49m
[38;5;244m#219 ComponentElement.performRebuild[39;49m
[38;5;244m#220 StatefulElement.performRebuild[39;49m
[38;5;244m#221 Element.rebuild[39;49m
[38;5;244m#222 BuildOwner.buildScope[39;49m
[38;5;244m#223 WidgetsBinding.drawFrame[39;49m
[38;5;244m#224 RendererBinding._handlePersistentFrameCallback[39;49m
[38;5;244m#225 SchedulerBinding._invokeFrameCallback[39;49m
[38;5;244m#226 SchedulerBinding.handleDrawFrame[39;49m
[38;5;244m#227 SchedulerBinding._handleDrawFrame[39;49m
[38;5;244m#231 _invoke (dart:ui/hooks.dart:253:10)[39;49m
[38;5;244m#232 _drawFrame (dart:ui/hooks.dart:211:3)[39;49m
(elided 3 frames from dart:async)
The AnimationController notifying status listeners was:
AnimationController#ac0aa(⏮ 0.000; paused; for MaterialPageRoute<dynamic>(null))
════════════════════════════════════════════════════════════════════════════════════════════════════
[38;5;248m════════ Exception caught by animation library ═════════════════════════════════[39;49m
[38;5;244mThe following assertion was thrown while notifying status listeners for AnimationController:[39;49m
setState() or markNeedsBuild() called during build.
[38;5;244mThis _ModalScope<dynamic> 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.[39;49m
[38;5;244mThe widget on which setState() or markNeedsBuild() was called was: _ModalScope<dynamic>-[LabeledGlobalKey<_ModalScopeState<dynamic>>#0c8ee][39;49m
[38;5;244mstate: _ModalScopeState<dynamic>#b0964[39;49m
[38;5;244mThe widget which was currently being built when the offending call was made was: CameraScreen[39;49m
[38;5;244mdirty[39;49m
[38;5;244mstate: _CameraScreenState#54b04[39;49m
[38;5;244mWhen the exception was thrown, this was the stack[39;49m
[38;5;244m#0 Element.markNeedsBuild.<anonymous closure>[39;49m
[38;5;244m#1 Element.markNeedsBuild[39;49m
[38;5;244m#2 State.setState[39;49m
[38;5;244m#3 _ModalScopeState._routeSetState[39;49m
[38;5;244m#4 ModalRoute.setState[39;49m
[38;5;244m...[39;49m
[38;5;244mThe AnimationController notifying status listeners was: AnimationController#ac0aa(⏮ 0.000; paused; for MaterialPageRoute<dynamic>(null))[39;49m
[38;5;248m════════════════════════════════════════════════════════════════════════════════[39;49m
Another exception was thrown: type 'Future<dynamic>' is not a subtype of type 'Widget'
[38;5;248m════════ Exception caught by widgets library ═══════════════════════════════════[39;49m
type 'Future<dynamic>' is not a subtype of type 'Widget'
[38;5;244mThe relevant error-causing widget was[39;49m
[38;5;248mCameraScreen[39;49m
[38;5;248m════════════════════════════════════════════════════════════════════════════════[39;49m
The builder function for MaterialPageRoute should return an Widget or class the implnentes from StatelessWidget or StatefullWidget, apparently CameraScreen is neither of those.
Your captureImageWithCamera does will return a Future<void> but the body of scaffold must be a widget, also is not clear what is the return type for displayStoryUploadScreen but also must be a widget.
if you need the value of a future to build your widget you'll need to use FutureBuilder to await it without looking the render tree.

Error: Class 'QuerySnapshot' has no instance getter 'data'

I'm trying to creat a UI screen with 3 tabs in it. RecentItem, ReviewItem and Profile. however there's some backend problem in recentitem widget. With the error shown: Class 'QuerySnapshot' has no instance getter 'data'.
Ps: The whole code is quite big hence I have shared a doc for the whole code: https://docs.google.com/document/d/1qs4ajPJ0DBjserBJ3iBZmPXPz1zTP7tIYSh8vceVQn8/edit?usp=sharing
RecentItems():
Widget RecentItems() {
return Padding(
padding: const EdgeInsets.all(10.0),
child: StreamBuilder(
stream: Firestore.instance
.collection("users")
.document(uid)
.collection("recent")
.snapshots(),
builder: (context, snapshot) {
print(snapshot.data);
List orders = List.from(Map.from(snapshot.data.data)['orders']);
Map order;
for (int i = 0; i < orders.length; i++) {
if (orders[i]['orderId'] == widget.map['orderId'] &&
orders[i]['homemaker'] == widget.map['homemaker']) {
order = orders[i];
break;
}
}
if (snapshot.data.isEmpty) {
return Center(
child:
Text("OOPS, Looks like no one is serving!"));
}
print(order);
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
print(snapshot.data.documents[0].data);
return Container(
height: 400,
child: ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.all(10.0),
width: MediaQuery
.of(context)
.size
.width,
height: 85,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(child: Text(
"${snapshot.data.documents[index]
.data["dishname"]}", style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold),)),
//Icon: how to access if food is veg or not
],
),
// SizedBox(height:5),
Row(
children: <Widget>[
Expanded(child: Text(
"${snapshot.data.documents[index]
.data["homemaker"]}",
style: TextStyle(fontSize: 10),)),
Text("${snapshot.data.documents[index]
.data["rating"]}",
style: TextStyle(fontSize: 15)),
Icon(
Icons.star, color: Colors.yellow.shade800,
size: 20,)
],
),
SizedBox(height: 5),
//How to access order date
Text(
"Ordered ${DateTime
.parse(order['order_placed_at']
.toDate()
.toString())
.day}/${DateTime
.parse(order['order_placed_at']
.toDate()
.toString())
.month}/${DateTime
.parse(order['order_placed_at']
.toDate()
.toString())
.year}}",
style: TextStyle(fontSize: 15.0,
fontWeight: FontWeight.bold),
),
],
),
),
);
}),
);
} //
}),
);
}
The Error Message is:
The getter 'data' was called on null.
Receiver: null
Tried calling: data
The relevant error-causing widget was:
StreamBuilder<QuerySnapshot> file:///C:/Flutter/Naniz_eats/lib/UserProfilePage.dart:434:14
════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (28940): Instance of 'QuerySnapshot'
════════ (3) Exception caught by widgets library ═══════════════════════════════════════════════════
Class 'QuerySnapshot' has no instance getter 'data'.
Receiver: Instance of 'QuerySnapshot'
Tried calling: data
The relevant error-causing widget was:
StreamBuilder<QuerySnapshot> file:///C:/Flutter/Naniz_eats/lib/UserProfilePage.dart:434:14
Several things or all might be causing this:
the print from the first line of builder. If snapshot was indeed empty you would already be calling data without first checking if it is empty.
snapshot.data.data which I think is a typo in the second line of builder
The fact that you are doing operations on snapshot without first checking for snapshot.hasData, snapshot.data.documents.length != 0 to ensure that you are not doing operations on null snapshots.
You should also be able to check specifically which line is causing the error by pressing on the error messages, one of the error messages should contain a link to the specific line (not shown in your question, should be somewhere between the long stacks of error messages)
This code:
Firestore.instance
.collection("users")
.document(uid)
.collection("recent")
.snapshots()
returns a Stream of type QuerySnapshot, the problem is here:
List orders = List.from(Map.from(snapshot.data.data)['orders']);
the code snapshot.data will return an instance of QuerySnapshot and QuerySnapshot does not contain a instance variable called data. So, if you want to a list of documents then you have to do the following:
List<DocumentSnapshot> orders = snapshot.data.documents;
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart#L17

Another exception was thrown: FormatException: Invalid number (at character 1)

Why does the error Another exception was thrown: FormatException: Invalid number (at character 1) occur on my screen for a few microseconds before all is back to normal. Sometimes it doesn't even occur. Below is my StreamBuilder function:
_delivered() {
print('In the delivered function:${resId},${customerId}, ');
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection('restaurants')
.document(resId)
.collection('customers')
.document(customer)
.collection('orders')
.where('deliveryTime', isGreaterThan: '')
.snapshots(),
builder: (context, snapshot) {
print('Does snapshop have data? ${snapshot.hasData}');
if (!snapshot.hasData) return Container();
List deliveredListFromServer = snapshot.data.documents;
return Expanded(
child: ListView(
shrinkWrap: true,
children: deliveredListFromServer.map((item) {
print('document id: ${item.documentID}');
return InkWell(
child: SizedBox(
height: 50,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 80,
child: Text(
item['orderBy']['username'],
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
SizedBox(
width: 5,
),
Expanded(
child: ListView(
scrollDirection: Axis.horizontal,
children: item['order'].map<Widget>((item) {
return SizedBox(
width: 80,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'${item['qty']} ${item['drinkName']}',
overflow: TextOverflow.ellipsis,
),
),
);
}).toList(),
), //
),
SizedBox(
width: 5,
),
SizedBox(
width: 60,
child: Text(DateFormat('h:mm a').format(
DateTime.fromMillisecondsSinceEpoch(
int.parse(item['deliveryTime'])))),
)
],
),
),
onTap: () {
_deliveredDetail(item);
},
);
}).toList(),
),
);
});
}
This is my console:
I/flutter (11506): In the delivered function:XufIsxA8a24lLhO6gTr1,zMrQmcoQwci9bVVRo6tx,
I/flutter (11506): Does snapshop have data? true
I/flutter (11506): document id: 1579534059562
I/flutter (11506): document id: 1579595374166
I/flutter (11506): Another exception was thrown: FormatException: Invalid number (at character 1)
I/flutter (11506): Does snapshop have data? true
I/flutter (11506): document id: 1579534059562
From the console, I don't even understand why it's bringing document id: 1579595374166 from the database. Only document id: 1579534059562 has a deliveryTime set. The database has 6 records, only one has a deliveryTime set. Others are empty "" strings.
So after a few milliseconds, everything works as expected i.e. the proper UI with only one item for the database showing on the screen. It looks like everything is back to normal the second time the stream returns only one document. In fact, the only time it doesn't bring the red screen is when the console looks like this:
I/flutter (11506): In the delivered function:XufIsxA8a24lLhO6gTr1,zMrQmcoQwci9bVVRo6tx,
I/flutter (11506): Does snapshop have data? false
I/flutter (11506): Does snapshop have data? true
I/flutter (11506): document id: 1579534059562
This also means the streamBuilder is passing incorrect data to the list (and probable source of error). Why is the query returning the wrong results sometimes?!
This error occurs when you are fetching a data which is null, I encountered the same issue and was able to solve it by removing that null data from my firestore database.
I would suggest you check the data in the collection from where you are fetching the list, one of the fields must be null there.
My answer may not be applicable to this instance, but I have also got the same error "Invalid number (at character 1)", the place where I get the error points me to where I have used the variable name of my TextEditingController
The problem with my case was that I have already used a TextEditingController with the same name (also not as a private variable) in another point of my application and have not disposed it after using.
After I disposed all of my TextEditingControllers my problem got solved !
if an error occurs in the parameter, you can add an isEmpty condition for your parameter value.
ex :
// define currency
final _controller = TextEditingController(); static const _locale = 'id'; static const _symbol = 'Rp. '; String _formatNumber(String s) =>
NumberFormat.decimalPattern(
_locale,
).format(s.isEmpty ? 0 : int.parse(s)); String get _currency =>
NumberFormat.compactSimpleCurrency( locale: _locale, name: _symbol).currencySymbol;
//textfield
TextfieldWidget( prefixText: Text(_currency, style: Theme.of(context).textTheme.subtitle1),
controller: _controller,
onChanged: (string) {
string =
'${_formatNumber(string.replaceAll(',', ''))}';
_controller.value = TextEditingValue(
text: string,
selection: TextSelection.collapsed(
offset: string.length ?? null),
);
}, ),
Ensure that you check that the value is not equal to "" or null
if (value != "")