The getter 'documents' was called on null shown for a while - firebase

Im trying to retrieve name of user from firebase on appBar. It successfully retrieves it. But it displays an error on screen for few seconds before showing name of user successfully. The error os
I/flutter (24143): The following NoSuchMethodError was thrown building
StreamBuilder(dirty, state:
I/flutter (24143): _StreamBuilderBaseState<QuerySnapshot,
AsyncSnapshot>#c10cf):
I/flutter (24143): The getter 'documents' was called on null.
I/flutter (24143): Receiver: null
I/flutter (24143): Tried calling: documents
Class Data{
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
CurrentUser _currentUser = Provider.of<CurrentUser>(context, listen: false);
return Scaffold(
backgroundColor: Colors.grey[600],
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text('Property Host'),
centerTitle: true,
actions: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
margin: new EdgeInsets.only(left: 50),
child: Text('Property Host',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 19),)),
StreamBuilder(stream: Firestore.instance.collection('users').where("uid", isEqualTo: userid).snapshots(),
// ignore: missing_return
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.data == null)
CircularProgressIndicator();
//final userDocument = snapshot.data;
//final title= snapshot.data.userocument['displayName']);
//CircularProgressIndicator();
return Expanded(
child: ListView.builder(
itemCount: snapshot.data.documents.length,
// ignore: missing_return
itemBuilder: (BuildContext context, int index) {
print(user.uid);
return user != null
? Container(
margin: EdgeInsets.only(top: 17, left: 40),
child: Text(
snapshot.data.documents.elementAt(index)['displayName']),
)
: IconButton(
icon: Icon(Icons.person),
// ignore: missing_return
onPressed: () {
Navigator.pushNamed(context, '/LoginScreen');
},
);
}
),
);
}

Use snapshot.hasData to ensure that you build the main widget (Expanded) after the data has been retrieved and use CircularProgessIndicator to hold its position before the data is returned
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData){
return Expanded(
child: ListView.builder(
itemCount: snapshot.data.documents.length,
// ignore: missing_return
itemBuilder: (BuildContext context, int index) {
print(user.uid);
return user != null
? Container(
margin: EdgeInsets.only(top: 17, left: 40),
child: Text(
snapshot.data.documents.elementAt(index)['displayName']),
)
: IconButton(
icon: Icon(Icons.person),
// ignore: missing_return
onPressed: () {
Navigator.pushNamed(context, '/LoginScreen');
},
);
}
),
);
}
else {
return CircularProgressIndicator();
}
}

Related

How to create streambuilder and listview with Firebase Realtime database data (Flutter chat app)

I'm building a flutter chat app for my personal learning project where the data will be retrieved from Firebase Realtime database.
I got this code from a tutorial but it is showing errors. How to solve this?
StreamBuilder(
stream: dbRef.onValue,
builder: (context, snapshot) {
if (snapshot.hasData) {
print("Error on the way");
messages.clear();
DataSnapshot dataValues = snapshot.data.snapshot; //Error: The getter snapshot is not defined for the type 'Object';
Map<dynamic, dynamic> values = dataValues.value;
values.forEach((key, values) {
messages.add(values);
});
return new ListView.builder(
shrinkWrap: true,
itemCount: messages.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Name: " + messages[index]["Text"]),
Text("Time: " + messages[index]["TextTime"]),
],
),
);
},
);
}
},
),
This solved the problem.
StreamBuilder(
stream: _dbRef.onValue,
builder: (context, snapshot) {
List<Message> messageList = [];
if (snapshot.hasData &&
snapshot.data != null &&
(snapshot.data! as DatabaseEvent).snapshot.value !=
null) {
final myMessages = Map<dynamic, dynamic>.from(
(snapshot.data! as DatabaseEvent).snapshot.value
as Map<dynamic, dynamic>); //typecasting
myMessages.forEach((key, value) {
final currentMessage = Map<String, dynamic>.from(value);
messageList.add(Message(
author: currentMessage['Author'],
authorId: currentMessage['Author_ID'],
text: currentMessage['Text'],
time: currentMessage['Time'],));
}); //created a class called message and added all messages in a List of class message
return ListView.builder(
reverse: true,
itemCount: messageList.length,
itemBuilder: (context, index) {
return ChattingDesign(
message: messageList[index],
dbpathToMsgChnl:
'TextChannels/${widget.channels['ChannelName']}/Messages',
showName: shouldShowName(
index,
messageList.length - 1,
messageList,
),
);
},
);
} else {
return Center(
child: Text(
'Say Hi...',
style: TextStyle(
color: Colors.white,
fontSize: 21,
fontWeight: FontWeight.w400),
),
);
}
},
),
According to the DataSnapshot Class Documentation there is no field called snapshot
I think there is a typo in your code.
Try this
StreamBuilder(
stream: dbRef.onValue,
builder: (context, snapshot) {
if (snapshot.hasData) {
print("Error on the way");
messages.clear();
DataSnapshot dataValues = snapshot.data! as DataSnapshot ; //here's the typo;
Map<dynamic, dynamic> values = dataValues.value;
values.forEach((key, values) {
messages.add(values);
});
return new ListView.builder(
shrinkWrap: true,
itemCount: messages.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Name: " + messages[index]["Text"]),
Text("Time: " + messages[index]["TextTime"]),
],
),
);
},
);
}
},
),

Why my widget is not returning the else block?

Why im getting this error when my list is empty?
[VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: 'package:cloud_firestore/src/query.dart': Failed assertion: line 435 pos 16: '(value as List).isNotEmpty': 'in' filters require a non-empty [List].
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
#2 Query.where
package:cloud_firestore/src/query.dart:435
#3 _MeineFreundeState.getalldata
package:wichtigdenyady/seitenleiste/meinefreunde.dart:48
<asynchronous suspension>
This is my code
Widget getBody(BuildContext context) {
return dataisthere == false
? Scaffold(body: Center(child: CircularProgressIndicator()))
: Stack(children: <Widget>[
Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(Icons.search),
onPressed: () {
Navigator.of(context)
.pushNamed(Searchuserinmeinebeitraege.route);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: RefreshIndicator(
onRefresh: _handleRefresh,
color: Colors.black,
strokeWidth: 4,
child: ListView(
children: [
Column(children: <Widget>[
SizedBox(
height: 5,
),
StreamBuilder(
stream: myVideos,
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}else { if (videos > 0) {
return StaggeredGridView.countBuilder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: ScrollPhysics(),
crossAxisCount: 3,
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot video =
snapshot.data.docs[index];
return InkWell(
onTap: () {
currentvideoindex = index;
NavigationService.instance
.navigateToRoute(MaterialPageRoute(
builder: (context) {
return MeineFreundeVideos(
video.data()['videourl'],
video.data()['uid'],
video.id,
currentvideoindex,
listofeachid);
}));
},
child: Card(
elevation: 0.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(25),
clipBehavior:
Clip.antiAliasWithSaveLayer,
child: Image.network(
video.data()['previewimage'],
fit: BoxFit.cover,
),
),
),
);
},
staggeredTileBuilder: (index) =>
...
);
} else {
return Center(
child: Padding(
padding:
const EdgeInsets.fromLTRB(0, 100, 0, 0),
child: Container(
child: Text(
"No Videos Yet",
style: TextStyle(
fontSize: 18, color: Colors.black),
),
And heres where I defined the list
getalldata() async {
List listOfIds = [];
String myID = FirebaseAuth.instance.currentUser.uid;
var idofotheruser = await FirebaseFirestore.instance
.collection('meinprofilsettings')
.doc(myID)
.collection('following')
.get();
following = idofotheruser.docs.length;
idofotheruser.docs.forEach((element) {
listOfIds.add(element.id);
});
print(listOfIds);
myVideos = FirebaseFirestore.instance
.collection('videos')
.where('uid', whereIn:listOfIds)
.snapshots();
var documents = await FirebaseFirestore.instance
.collection('videos')
.where('uid', whereIn: listOfIds)
.get();
setState(() {
videos = documents.docs.length;
print(videos);
});
So its loading(returning the circularprogressindicator) when the list is empty and not stopping. When its not then it works . Hope anyone can help. If you need more information please leave a comment .ALso you need more code also please leave comment
The uid field is not an array, but you're using arrayContains to query it. That won't work. If you want to check if a single-value field has one of many values, use the in operation:
.where('uid', whereIn: listOfIds)

Flutter Firebase failed assertion: line 360 pos 10: 'data != null'

Widget BlogsList() {
return Container(
color: UniversalVariables.blackColor,
child: blogsStream != null
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot) {
if (!snapshot.hasData || snapshot.data.documents.isEmpty) ;
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return BlogsTile(
authorName: snapshot
.data.documents[index].data['authorName'],
title: snapshot.data.documents[index].data["title"],
description:
snapshot.data.documents[index].data['desc'],
imgUrl:
snapshot.data.documents[index].data['imgUrl'],
);
});
},
)
],
)
: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
); }
I want to make it mandatory. giving a red screen and open.I want to solve this problem. I am pulling data with Firebase. I'm having trouble switching between pages, but could not solve my error.
The error occurred is in your builder, you returned the ListView whether snapshot.hasData is true or not.
Try
builder: (context, snapshot) {
if (!snapshot.hasData || snapshot.data.documents.isEmpty){
return Center(child: Text("Loadin..."));
}
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return BlogsTile(
authorName: snapshot.data.documents[index].data['authorName'],
title: snapshot.data.documents[index].data["title"],
description:snapshot.data.documents[index].data['desc'],
imgUrl:snapshot.data.documents[index].data['imgUrl'],
);
});
},

how to convert the data coming from snapshot into List to fit in this column?

my this code is showing me error that querysnapshot is not a subtype of a list. can you edit my code and tell me how to make this error free.
buildProfilePosts() {
if (_isLoading) {
return Center(
child: Text(
"Loading...",
style: TextStyle(fontFamily: "QuickSand"),
),
);
}
return StreamBuilder(
stream: postsRef.document(widget.profileId).collection('userPosts').orderBy('timestamp', descending: true).snapshots(),
builder: (context, snapshot) {
return Column(
children: snapshot.data,
);
}
);
}
children is a property inside the widget Column, it takes a list of widgets. You should do the following:
child: Column(children: <Widget>[
StreamBuilder(
stream: postsRef.document(widget.profileId).collection('userPosts').orderBy('timestamp', descending: true).snapshots(),,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
contentPadding: EdgeInsets.all(8.0),
title:
Text(snapshot.data.documents[index].data["name"]),
);
});
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
}
return CircularProgressIndicator();
},
),
]),
Assuming you have a name field in your document.
Try
Column(
children: <Widget>[
...List.generate(
snapshot.data.length,
(index) {
return Container(
child: Text(snapshot.data[index].yourobject),
);
},
),
],
),

NoSuchMethodError: Class 'QuerySnapshot' has no instance method '[]'

Im trying to get posts(images) for every user.User's id are stored in posts collection and every userid document will have a subcollection will contains all posts document.but im getting this error.
The following NoSuchMethodError was thrown building:
Class 'QuerySnapshot' has no instance method '[]'.
Receiver: Instance of 'QuerySnapshot'
Tried calling: []("mediaUrl")
this is the code.
getPost(){
return FutureBuilder(
future: Firestore.instance.collection('posts').document(user.id
).collection('userPosts').getDocuments(),
// ignore: missing_return
builder: (context,snapshot) {
if (snapshot.hasData) {
return
Container(
height: 200,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
child: Image.network(snapshot.data["mediaUrl"],)
);
}
),
],
),
);
}
if (!snapshot.data ) {
return Text('No posts');
} else {
return CircularProgressIndicator();
}
}
);
}`
If your media url is inside a document then try this :
Image.network(snapshot.data.documents[index]["mediaUrl"],)
Full code with another approach :
getPost(){
return FutureBuilder(
future: Firestore.instance.collection('posts').document(user.id
).collection('userPosts').getDocuments(),
// ignore: missing_return
builder: (context,snapshot) {
if (snapshot.hasData) {
return
Container(
height: 200,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot docSnapshot = snapshot.data.documents[index];
return Image.network(docSnapshot["mediaUrl"],)
);
}
),
],
),
);
}
if (!snapshot.data ) {
return Text('No posts');
} else {
return CircularProgressIndicator();
}
}
);
}

Resources