I am having an error as regards fetching data from firestore using futureBuilder. When I do a print of snapshot.data without calling a Text widget, I get an instance of 'User'.
Without Calling author.fullname
body: ListView.builder(
itemCount: _posts.length,
itemBuilder: (BuildContext context, int index) {
Post post = _posts[index];
return FutureBuilder(
future: DatabaseService.getUserWithId(post.authorid),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
print(snapshot.data);
User author = snapshot.data;
return Column(
children: <Widget>[],
);
}
}
return SizedBox.shrink();
Output
Performing hot restart...
Restarted application in 1,146ms.
flutter: Instance of 'User'
flutter: Instance of 'User'
However when I try to call for the fullname of the user from firestore, it returns null
body: ListView.builder(
itemCount: _posts.length,
itemBuilder: (BuildContext context, int index) {
Post post = _posts[index];
return FutureBuilder(
future: DatabaseService.getUserWithId(post.authorid),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
print(snapshot.data);
User author = snapshot.data;
return Column(
children: <Widget>[
Text(author.fullname)
],
);
}
}
return SizedBox.shrink();
Output
Performing hot restart...
Restarted application in 1,042ms.
flutter: Instance of 'User'
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
flutter: The following assertion was thrown building FutureBuilder<User>(dirty, state:
flutter: _FutureBuilderState<User>#23d74):
flutter: A non-null String must be provided to a Text widget.
flutter: 'package:flutter/src/widgets/text.dart':
flutter: Failed assertion: line 285 pos 10: 'data != null'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: The relevant error-causing widget was:
flutter: FutureBuilder<User> file:///Users/momo/Desktop/combine/lib/screens/home.dart:65:18
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #2 new Text (package:flutter/src/widgets/text.dart:285:10)
flutter: #3_HomeState.build.<anonymous closure>.<anonymous closure> (package:combine/screens/home.dart:75:23)
flutter: #4 _FutureBuilderState.build (package:flutter/src/widgets/async.dart)
flutter: #5 StatefulElement.build (package:flutter/src/widgets/framework.dart:4334:27)
flutter: #6 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4223:15)
flutter: #7 Element.rebuild (package:flutter/src/widgets/framework.dart:3947:5)
flutter: #8 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2432:33)
flutter: #9 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:773:20)
flutter: #10 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:283:5)
flutter: #11 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1102:15)
flutter: #12 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1041:9)
flutter: #13 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:957:5)
flutter: #17 _invoke (dart:ui/hooks.dart:259:10)
flutter: #18 _drawFrame (dart:ui/hooks.dart:217:3)
flutter: (elided 5 frames from class _AssertionError and package dart:async)
User Class
class User {
final String id;
final String email;
final String password;
final String fullname;
User(
{this.id,
this.email,
this.password,
this.fullname,});
factory User.fromDoc(DocumentSnapshot doc) {
return User(
id: doc.documentID,
email: doc['email'],
fullname: doc['fullname'],
);
}
}
You must provide an empty text in case the name is null
return Column(
children: <Widget>[
Text(author.fullname == null? '' : author.fullname)
],
);
Related
I am creating a Flutter application that uses Firebase. I keep getting an error when trying to use Firebase.initializeApp().
main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:myapp/screens/home/home.dart';
import 'package:myapp/screens/landing/landing.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
Future<User> currentUser = FirebaseAuth.instance.currentUser as Future<User>;
return FutureBuilder<User>(
future: currentUser,
builder: (BuildContext context, AsyncSnapshot<User> snapshot){
if (snapshot.hasData){
User user = snapshot.data;
return HomeScreen();
}
return LandingScreen();
}
);
}
}
Error
E/flutter (31443): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Failed assertion: boolean expression must not be null
E/flutter (31443): #0 new FirebaseOptions.fromMap (package:firebase_core_platform_interface/src/firebase_options.dart:78:47)
E/flutter (31443): #1 MethodChannelFirebase._initializeFirebaseAppFromMap (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:44:23)
E/flutter (31443): #2 ListMixin.forEach (dart:collection/list.dart:86:13)
E/flutter (31443): #3 MethodChannelFirebase._initializeCore (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:34:10)
E/flutter (31443): <asynchronous suspension>
E/flutter (31443): #4 MethodChannelFirebase.initializeApp (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:75:13)
E/flutter (31443): #5 Firebase.initializeApp (package:firebase_core/src/firebase.dart:43:25)
E/flutter (31443): #6 main (package:myapp/main.dart:12:18)
E/flutter (31443): #7 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:231:25)
E/flutter (31443): #8 _rootRun (dart:async/zone.dart:1190:13)
E/flutter (31443): #9 _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (31443): #10 _runZoned (dart:async/zone.dart:1630:10)
E/flutter (31443): #11 runZonedGuarded (dart:async/zone.dart:1618:12)
E/flutter (31443): #12 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:223:5)
E/flutter (31443): #13 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter (31443): #14 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter (31443):
My main.dart line 12 is Firebase.initializeApp()
What am I missing?
pubspec.yaml
name: myapp
description: Myapp
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cloud_firestore: ^0.14.4
firebase_auth: ^0.18.4+1
firebase_core: 0.5.3
cupertino_icons: ^1.0.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
Update
I have been able to get around the error by entirely changing my structure of main.dart like below. This was taken from a Flutter example:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// Create the initialization Future outside of `build`:
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
#override
Widget build(BuildContext context) {
return FutureBuilder(
// Initialize FlutterFire:
future: _initialization,
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
return MaterialApp(
title: 'MyApp',
home: LandingScreen(),
);
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
return MaterialApp(
title: 'MyApp',
home: LandingScreen(),
);
}
// Otherwise, show something whilst waiting for initialization to complete
return MaterialApp(
title: 'MyApp',
home: LandingScreen(),
);
},
);
}
}
While this does seem to work, I would still love to know why the other structure was not working, when it seems that the other structure is what is recommended in most docs.
When i first load the widget it gives me an error but works as expected. When I go to another screen then back though it will duplicated the data from the future.
#override
Widget build(BuildContext context) {
final userdata = context.watch<UserDataNotifier>();
UserData data = Provider.of<UserData>(context);
double h = MediaQuery.of(context).size.height;
// print(data);
return StreamBuilder(
stream: Stream.fromFuture(data.getTheUserClasses),
builder: (context, snapshot) {
snapshot.data.toString();
return Scaffold(
backgroundColor: Color(0xff3DDC97),
appBar: AppBar(
backgroundColor: Color(0xff7211E0),
title: userdata.user == null
? CircularProgressIndicator()
: Text(userdata.user.firstName ?? ""),
),
body: Container(
// padding: EdgeInsets.symmetric(vertical: h / 8),
padding: EdgeInsets.fromLTRB(0, h / 8, 0, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: h * .5,
child: data.classList == null
? Loading()
: data.classList.isEmpty
? Loading()
: UserClassList(
data: data.classList,
)),
RaisedButton(
child: Text("Add Class"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PickFromAllClasses()))
.then((value) => value ? _refresh() : null);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Colors.blue,
)
],
)),
);
},
);
}
here is how I get the data
class UserData {
String uid;
String firstName;
int rating;
List<String> classes;
List<ClassData> classList = List<ClassData>();
UserData.fromMap(Map<String, dynamic> data) {
firstName = data['firstname'] ?? "";
rating = data['rating'] ?? "";
classes = data['classes'].cast<String>() ?? "";
}
List<ClassData> get cs => classList;
set cs(List<ClassData> s) {
cs = s;
}
Future get getTheUserClasses async {
for (String c in classes) {
DocumentSnapshot classsnapshot =
await Firestore.instance.collection("Classes").document(c).get();
final data =
ClassData.fromUserMap(classsnapshot.data, classsnapshot.documentID);
if (data != null) {
classList.add(data);
// print(data.classdescription);
}
}
cs = classList;
}
UserData({this.firstName, this.rating, this.classes});
}
Here is the error I get when I load this widget.
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building YourClasses(dirty, dependencies: [MediaQuery,
flutter: _InheritedProviderScope<UserDataNotifier>, _InheritedProviderScope<UserData>], state:
flutter: _YourClassesState#4bf6d):
flutter: The getter 'getTheUserClasses' was called on null.
flutter: Receiver: null
flutter: Tried calling: getTheUserClasses
flutter:
flutter: The relevant error-causing widget was:
flutter: YourClasses
flutter: file:///Users/devintripp/Desktop/flutter_apps.no_sync/discoverytutors/lib/Screens/LoggedIn/TutorsView/tutors.dart:148:65
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
flutter: #1 _YourClassesState.build (package:disc_t/Screens/LoggedIn/Classes/yourclasses.dart:66:38)
flutter: #2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4619:28)
flutter: #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4502:15)
flutter: #4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11)
flutter: #5 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
flutter: #6 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5)
flutter: #7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4666:11)
flutter: #8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5)
flutter: ... Normal element mounting (24 frames)
flutter: #32 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
flutter: #33 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)
flutter: ... Normal element mounting (119 frames)
flutter: #152 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
flutter: #153 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18)
flutter: #154 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5580:32)
flutter: #155 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5957:17)
flutter: #156 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #157 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16)
flutter: #158 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11)
flutter: #159 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
flutter: #160 StatefulElement.update (package:flutter/src/widgets/framework.dart:4707:5)
flutter: #161 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #162 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16)
flutter: #163 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
flutter: #164 ProxyElement.update (package:flutter/src/widgets/framework.dart:4862:5)
flutter: #165 _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:181:11)
flutter: #166 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #167 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5837:14)
flutter: #168 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #169 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16)
flutter: #170 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11)
flutter: #171 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
flutter: #172 StatefulElement.update (package:flutter/src/widgets/framework.dart:4707:5)
flutter: #173 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #174 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5837:14)
flutter: #175 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #176 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5837:14)
flutter: #177 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #178 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16)
flutter: #179 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
flutter: #180 StatelessElement.update (package:flutter/src/widgets/framework.dart:4583:5)
flutter: #181 Element.updateChild (package:flutter/src/widgets/framework.dart:3201:15)
flutter: #182 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16)
flutter: #183 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11)
flutter: #184 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
flutter: #185 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2627:33)
flutter: #186 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:20)
flutter: #187 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:284:5)
flutter: #188 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1113:15)
flutter: #189 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1052:9)
flutter: #190 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:968:5)
flutter: #194 _invoke (dart:ui/hooks.dart:261:10)
flutter: #195 _drawFrame (dart:ui/hooks.dart:219:3)
flutter: (elided 3 frames from dart:async)
Here is the screen that is loaded at first.
then when it duplicates it gets the same data 3 times. This is after i refresh this widget.
Instead of using a StreamBuilder, use a FutureBuilder.
Instead of creating your Future on every build, create the Future once and save it to a variable in your state, so it does not get called again and again, but only once, no matter how many times your build method is called.
Stream.fromFuture() does not cover your use case. It will not update if new elements are added or elements are deleted (since it just gets the elements from a Future).
In your case you might want to do something like the following:
Stream<List<YourModel>> getUserList() {
return Firestore.instance.collection('Classes')
.snapshots()
.map((snapShot) => snapShot.documents
.map((document) => Yourmodel.fromDocument(document.data)
.toList());
}
Furthermore, in order to avoid the error you see in the console, you need to check whether the document has data (e.g. if (document.hasData())) and return the widget to be displayed if no data is available yet.
I updated the cloud firestore yesterday. And, I surprised everything about firestore became wrong. I tried to update my code but I still getting an error with the Future builder. Here is the code and the error. The code was ok before the update.
Future getposts() async{
await Firebase.initializeApp();
var firestore = FirebaseFirestore.instance;
QuerySnapshot qn = await firestore.collection("Restaurants").get();
return qn.docs;}
FutureBuilder(
future: getposts(),
builder: (_,snapshot){
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);}
else{
return ListView.builder(
itemCount: snapshot.data().length,
itemBuilder: (_,index){
return Center(
child: Text(snapshot.data()[index].data()["name"]),
);
},);
}
},
),
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#2c7a5):
Class 'List' has no instance method 'call'.
Receiver: Instance(length:2) of '_GrowableList'
Tried calling: call()
The relevant error-causing widget was:
FutureBuilder file:///C:/Users/youse/AndroidStudioProjects/new_app/lib/screens/main_page.dart:226:23
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _MainPageState.build. (package:new_app/screens/main_page.dart:235:55)
#2 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:740:55)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4663:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4546:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
Thanks for help. I solved the issue by removing the parenthesis in the first data. And here is the correct code.
Future getposts() async{
await Firebase.initializeApp();
var firestore = FirebaseFirestore.instance;
QuerySnapshot qn = await firestore.collection("Restaurants").get();
return qn.docs;}
FutureBuilder(
future: getposts(),
builder: (_,snapshot){
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);}
else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_,index){
return Center(
child: Text(snapshot.data[index].data()["name"]),
);
},);
}
},
),
I am trying get User Name through a document stored in users collection in cloud firestore but my build method runs before the data is received.
The initState(){} method does not wait for uidDetails() to complete and therefore null values are passed in DoctorListStream(currentUserName) . Since the initState(){}` method cannot be made async I want to know what can be done to fix this. I have also tried to implement both StreamBuilder and FutureBuilder but failed.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '../components/doc_list_retriever.dart';
class ListOfDoctors extends StatefulWidget {
#override
_ListOfDoctorsState createState() => _ListOfDoctorsState();
}
class _ListOfDoctorsState extends State<ListOfDoctors> {
final _auth = FirebaseAuth.instance;
final _fStore = Firestore.instance;
String currentUserUid;
String currentUserName;
#override
void initState() {
// TODO: implement initState
super.initState();
uidDetails();
}
void uidDetails() async {
final FirebaseUser user = await _auth.currentUser();
currentUserUid = user.uid;
print(currentUserUid + 'from user details');
await Firestore.instance
.collection('users')
.document(currentUserUid)
.get()
.then((DocumentSnapshot) {
currentUserName = DocumentSnapshot.data['name'].toString();
});
print(currentUserName + ' from uid Details');
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF1D1E33),
body: SafeArea(
child: Column(
children: <Widget>[
Text(
'Doctors:',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 40, color: Colors.white70),
),
DoctorListStream(currentUserName),
],
),
),
);
}
}
CONSOLE :
Performing hot restart...
Syncing files to device AOSP on IA Emulator...
Restarted application in 848ms.
I/BiChannelGoogleApi(27263): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq#95a83d7
D/FirebaseAuth(27263): Notifying id token listeners about user ( 5TlH5zoCqfWDNDlAgvIsc5yAHPA3 ).
I/flutter (27263): 5TlH5zoCqfWDNDlAgvIsc5yAHPA3from user details
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#044e7):
The method '+' was called on null.
Receiver: null
Tried calling: +(" from doctor list stream")
The relevant error-causing widget was:
StreamBuilder<QuerySnapshot> file:///D:/projects/clinic/lib/components/doc_list_retriever.dart:14:12
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 DoctorListStream.build.<anonymous closure> (package:clinic/components/doc_list_retriever.dart:26:27)
#2 StreamBuilder.build (package:flutter/src/widgets/async.dart:509:81)
#3 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:127:48)
#4 StatefulElement.build (package:flutter/src/widgets/framework.dart:4623:28)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (27263): Dhruv from uid Details
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
A RenderFlex overflowed by 99670 pixels on the bottom.
The relevant error-causing widget was:
Column file:///D:/projects/clinic/lib/screens/list_of_doctors.dart:43:16
════════════════════════════════════════════════════════════════════════════════════════════════════
I would opt to using a stream builder to get the user data. sample implementation
String username;
body: StreamBuilder(
stream: Firestore.instance
.collection('users')
.document(userid)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SpinKitDoubleBounce(
color: Colors.blue,
);
}
var userDoc = snapshot.data;
userName = userDoc["name"];
return .... //your other widgets
I am getting this error while trying to fetch user data from the cloud_firestore but it's only getting me this error when for the first time, users login to the app and navigate to the profile screen. if I hot restart or rerun the app, while in login state error goes away.
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══
flutter: The following NoSuchMethodError was thrown building StreamBuilder<DocumentSnapshot>(dirty, state:
flutter: _StreamBuilderBaseState<DocumentSnapshot, AsyncSnapshot<DocumentSnapshot>>#f33a1):
flutter: The method '[]' was called on null.
flutter: Receiver: null
flutter: Tried calling: []("name")
flutter:
flutter: User-created ancestor of the error-causing widget was:
flutter: SliverFillRemaining
flutter: file:///Users/ishangavidusha/Development/MUD/mud_mobile_app/lib/screens/profile_screen.dart:102:13
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
flutter: #1 new User.from (package:mud_mobile_app/models/user_model.dart:23:22)
flutter: #2 _ProfileScreenState.build.<anonymous closure> (package:mud_mobile_app/screens/profile_screen.dart:107:38)
flutter: #3 StreamBuilder.build (package:flutter/src/widgets/async.dart:425:74)
flutter: #4 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:125:48)
flutter: #5 StatefulElement.build (package:flutter/src/widgets/framework.dart:4047:27)
flutter: #6 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3941:15)
flutter: #7 Element.rebuild (package:flutter/src/widgets/framework.dart:3738:5)
flutter: #8 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2348:33)
flutter: #9 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:760:20)
flutter: #10 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:280:5)
flutter: #11 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1033:15)
flutter: #12 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:975:9)
flutter: #13 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:891:5)
flutter: #17 _invoke (dart:ui/hooks.dart:249:10)
flutter: #18 _drawFrame (dart:ui/hooks.dart:207:3)
flutter: (elided 3 frames from package dart:async)
Emulator Screenshot
And this is the user model I use >
class User {
final String id;
final String name;
final String profileImageUrl;
final String email;
User({this.id, this.name, this.profileImageUrl, this.email});
factory User.fromDoc(DocumentSnapshot doc) {
return User(
id: doc.documentID,
name: doc['name'],
profileImageUrl: doc['profileImageUrl'],
email: doc['email'],
);
}
}
FutureBuilder >
SliverFillRemaining(
child: FutureBuilder(
future: _getUserData(widget.userId),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(50.0),
child: Center(
child: CircularProgressIndicator(),
),
);
}
User user = User.fromDoc(snapshot.data);
return Column(
children: <Widget>[
Padding(...),
Container(...),
Container(...),
],
);
}
)
)
And the Funtion DocumentSnapshot return >
Future<DocumentSnapshot> _getUserData(userId) async {
return Firestore.instance.collection('users').document(userId).get();
}
"StreamBuilder dirty state" warnings are usually shown if the snapshot data doesn't have a safety check. This ensures that the snapshot contains data. However, it seems if (!snapshot.hasData) is set as a safety check on the snippet you've provided.
From the details you've given, the error seems to only occur during first user login, but the error goes away on hot restart or app restart. I suggest checking if the method _getUserData(String userId) is able to receive the userId upon the first user login where the error usually occurs. Null seems to be passed on where the error occurs based from the logs you've provided.
flutter: The method '[]' was called on null.
flutter: Receiver: null
flutter: Tried calling: []("name")
FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
return Text("Full Name: ${data['full_name']} ${data['last_name']}");
}
return Text("loading");
If you are using above similar type code and then get same error , check the firebase documentId in collection name and snapshot