Error: Class '_JsonDocumentSnapshot' has no instance getter 'docs' - firebase

i am trying to get list of a particular uid document from firebase here is the code
StreamBuilder(
stream: firestore
.collection('interest')
.doc('${auth.currentUser.uid}')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return Container();
});
}),
Error:
Class '_JsonDocumentSnapshot' has no instance getter 'docs'.
Receiver: Instance of '_JsonDocumentSnapshot'
Tried calling: docs
my collection
i am try to get the list from this document uid
Thanks

I had a similar issue and I tried using explicit (BuildContext context, AsyncSnapshot snapshot) and it worked for me, also I create the listview without the builder:
ListView(
children: myList.map((object) {
return myWidget(object: object);
}).toList(),

Related

when fetching firestore database "itemCount: snapshot.data.documents.length" is not working anymore. does anyone know how to solve this problem?

this is the code:...............
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Practice Firebase"),
),
body: StreamBuilder(
stream:
FirebaseFirestore.instance.collection("Animals").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: const CircularProgressIndicator.adaptive(),
);
} else {
return ListView.builder(
itemCount: snapshot.data?.documents.length,
itemBuilder: (context, index) {
return ListTile(
title: snapshot.data.documents[index]["name"],
);
});
}
}));
}
}
The getter 'documents' isn't defined for the type 'Object'.
Try importing the library that defines 'documents', correcting the name to the name of an existing getter, or defining a getter or field named 'documents'
You can try to use the code skeleton below (here I have an own class MyAnimal so I can use members instead of map):
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('Animals')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
// handle error
return const Text('Error');
}
if (snapshot.connectionState == ConnectionState.waiting) {
// return progress indicator widget
return const Center(child: CircularProgressIndicator());
}
// here you should get the streamed documents like:
// snapshot.data!.docs
// so to build a ListView for example:
return ListView(
children:
snapshot.data!.docs.map((DocumentSnapshot document) {
final animal = document.data() as MyAnimal;
return ListTile(
title: Text(animal.name!),
);
}).toList(),
);
})
I had the same problem and this fixed it for me. So basically you need to give the snapshot the datatype of AsyncSnapshotsince .docscannot be called on an Object type.
StreamBuilder(
builder: (context, AsyncSnapshot snapshot) {
return ListView.builder(
itemCount: snapshot.data?.docs.length,
just declare the dataType of builder arguments..i mean,
builder:(BuildContext context,AsyncSnapshot snapShot)
enter image description here
Well actually, if you do this - you can access docs and length ...
builder: (BuildContext ctx, AsyncSnapshot LessThanSign QuerySnapshot GreaterThanSign streamSnapShot){}

i got this error when i am trying to use snapshot.data.docs.length in listview.buider: The getter 'docs' isn't defined for the type 'Object'

I am trying to fetch data from firebase to list all the documents in a listview builder the code is still not completed in term of displaying the database filed in the code. this is the error: The getter 'docs' isn't defined for the type 'Object'
Container(
child: StreamBuilder<Object>(
stream: _firestore
.collection('Patient')
.doc(_auth.currentUser.email)
.collection("Diabetes")
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount:
snapshot.data.docs.length, // here is the error "docs"
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshot.data.docs[index]; // also another error "docs"
return Container();
});
}
return Center(
child: CircularProgressIndicator(),
);
}),
)
You should replace snapshot.data.docs.length with snapshot.data.length
Container(
child: StreamBuilder<Object>(
stream: _firestore
.collection('Patient')
.doc(_auth.currentUser.email)
.collection("Diabetes")
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot = snapshot.data[index];
return Container();
});
}
return Center(
child: CircularProgressIndicator(),
);
}),
)
I solved the problem by replacing StreamBuilder<Object> with StreamBuilder<QuerySnapshot>. by default the StreamBuilder comes in this form StreamBuilder<Object>

"NoSuchMethodError: The getter 'docs' was called on null" Error Flutter Firebase

I'm getting the error "NoSuchMethodError: The getter 'docs' was called on null. Receiver: null Tried Calling: docs" whenever I try to use .orderby("POST_ID", descending: true. If someone has an answer to why I'm getting this error and how to fix it please help!
Here is my code:
Container(
margin: EdgeInsets.only(top: 100.0),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("Cities")
.doc(globals.selectedCity)
.collection("Posts")
.orderBy("POST_ID", descending: true)
.where("Category", isEqualTo: globals.selectedCategory)
.snapshots(),
builder: (context, postSnapshot) {
return ListView.builder(
itemCount: postSnapshot.data.docs.length,
itemBuilder: (BuildContext context, int index) {
switch (postSnapshot.data.docs[index]["Type"]) {
case "Image":
return new ImageCard(
imageLink: postSnapshot.data.docs[index]
["ImageLink"],
imageDescription: postSnapshot.data.docs[index]
["ImageDescription"],
posterName: postSnapshot.data.docs[index]
["PosterName"],
);
break;
case "Text":
return new TextCard(
postText: postSnapshot.data.docs[index]
["PostText"],
posterName: postSnapshot.data.docs[index]
["PosterName"],
);
break;
Problem is here:
(postSnapshot.data.docs[index]["Type"])
You have to ensure first that you got the data from firestore. In your case when connection state is connecting or if snapshot has error you invoke docs on null object. Consider building widget tree with checks like this:
class UserInformation extends StatelessWidget {
#override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return StreamBuilder<QuerySnapshot>(
stream: users.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return new ListView(
children: snapshot.data.docs.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document.data()['full_name']),
subtitle: new Text(document.data()['company']),
);
}).toList(),
);
},
);
}
}

Correct use of Streams with Flutter-Listview

I am trying to display a realtime chat-screen in flutter with with firebase-firestore (equal to the homescreen of whatsapp).
Working: Creating a list of all the contacts "peers". Have a Look at my Listview:
Container(
child: StreamBuilder(
stream:
//FirebaseFirestore.instance.collection('users').snapshots(),
FirebaseFirestore.instance
.collection('users')
.doc(currentUserId)
.collection('peers')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
);
} else {
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) =>
buildItem(context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
},
),
),
not working: Loading specific data for each tile like last message or name. I cant query this at the time of creating my first list (first query returns peer-ids, second returns userdata of a peer-id). My buildItem method consists of another streambuilder, however, as soon as the first streambuilder makes changes, the app freezes.
Widget buildItem(BuildContext context, DocumentSnapshot document) {
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(document.data()['peerId'])
.snapshots(),
builder: ...
Is this the proper way to nest streams? Simple Listviews are documented quite well, but i couldn't find a good example on this on google. Any help is appreciated.
Try creating your stream just once in initState and pass it onto this method:
//in initState
peersStream = FirebaseFirestore.instance
.collection('users')
.doc(currentUserId)
.collection('peers')
.snapshots(),
Then use stream: peersStream in the StreamBuilder.
Also, it is recommended to use widget-classes over methods for widgets: https://stackoverflow.com/a/53234826/5066615

Nesting two stream builders causing bad state error

I am fetching data from two different firestore collections and this is my code
StreamBuilder(
stream: Firestore.instance.collection('items').snapshots(),
builder: (BuildContext context, snapshot){
if(snapshot.connectionState == ConnectionState.waiting){
return CupertinoActivityIndicator();
}
if(snapshot.data != null){
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context,index){
return Column(
children: <Widget>[
Text(snapshot.data.documents[index]['name']),
Text(snapshot.data.documents[index]['color']),
Text(snapshot.data.documents[index]['lifetime']),
Container(
child: StreamBuilder(
stream: Firestore.instance.collection('users')
.document(userid).collection('Quantity')
.document(snapshot.data.documents[index]['id']).snapshots(),
builder: (BuildContext context, snap){
if(snapshot.connectionState == ConnectionState.waiting){
return CupertinoActivityIndicator();
}
if(snap.data != null){
return Container(
child: Text(snap.data.documents.length)
);
}
},
),
)
],
);
});
}
},
)
It is giving me error but when I use futurebuilder inside streambuilder everything works fine and I also used stream broadcast but it is also giving me same error.
Here is the code which I used for broadcast stream
StreamController _controller = StreamController.broadcast();
Stream getItems() async*{
Firestore.instance.collection('items').snapshots().listen((data){
_controller.add(data);
})
yield* _controller.stream;
}
You shouldn't create a new Stream inside the StreamBuilder. When you do:
StreamBuilder(
stream: Firestore.instance.collection('items').snapshots(),
And
StreamBuilder(
stream: Firestore.instance.collection('users')
.document(userid).collection('Quantity')
.document(snapshot.data.documents[index]['id']).snapshots(),
Each time your build() function is called a new StreamBuilder is created, so Firestore.instance.collection()...snapshots() is called, returning a new Stream each time.
You should convert your widget to a StatefulWidget and initialize your Stream on initState(), passing it as a class variable to your StreamBuilder. The nested StreamBuilder can also be transformed into a StatefulWidget and created in place, but initialized on the same manner. Just pay attention that you might need a Key for showing it correctly on a ListView.
Also if you want to convert a Single Subscription Stream to a Broadcast Stream you just have to call asBroadcastStream to convert it.

Resources