I'm trying to get the length for ListViewBuilder ItemCount with snapshot.data.docs.length but I get the error:
"The getter 'docs' isn't defined for the class 'Object'."
Here is my code:
StreamBuilder<Object>(
stream: FirebaseFirestore.instance.collection('recipe').doc(_user).collection('Food').snapshots(),
builder: (context, snapshot) {
return ListView.builder(
padding: EdgeInsets.only(left: 15),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return RecipeCards(
);
},
);
}
),
I solved the problem by using:
StreamBuilder<QuerySnapshot>
Instead of:
StreamBuilder<Object>
Related
How can use firestore using where and orderby in flutter?
When I wanna to use both, I got the error.
Exception has occurred.
_CastError (Null check operator used on a null value)
code
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Posts')
.where('country', isEqualTo: user.country)
//.where('country', isEqualTo: 'Australia')
.orderBy('time', descending: true)
.snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
//print(user.country);
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) => Container(
margin: EdgeInsets.symmetric(
horizontal: width > webScreenSize ? width * 0.3 : 0,
vertical: width > webScreenSize ? 15 : 0),
child: PostCard(
snap: snapshot.data!.docs[index],
),
),
);
},
So, why I could not got the data? I'd got the user.value.
The problem is that you're telling Flutter that snapshot.data is guaranteed to have a value, when in reality it doesn't here:
return ListView.builder(
itemCount: snapshot.data!.docs.length,
I recommend reading the documentation for StreamBuilder again, as there are many more states than snapshot.connectionState == ConnectionState.waiting that you need to handle.
For example, there could be an error, or there could be no data for another reason:
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Posts')
.where('country', isEqualTo: user.country)
.orderBy('time', descending: true)
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
// 👇 Handle error
if (snapshot.hasError) {
return const Center(
child: Text(snapshot.error),
);
}
// 👇 Handle lack of data
if (!snapshot.hasData) {
return const Center(
child: Text("Something when wrong - no data available"),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) => Container(
margin: EdgeInsets.symmetric(
horizontal: width > webScreenSize ? width * 0.3 : 0,
vertical: width > webScreenSize ? 15 : 0),
child: PostCard(
snap: snapshot.data!.docs[index],
),
),
);
I want to access data from firestore but there are errors, how can i do that?
I cant use .docs in snapshot.
StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
Stream:
getChatRoomMessages(chatRoomId) async {
return FirebaseFirestore.instance.collection("chatRooms").doc(chatRoomId).collection("chats").orderBy("ts", descending: true).snapshots();}
in the StreamBuilder you have to use AsyncSnapshot in with your snapshot property. That was what got it working for me
StreamBuilder<QuerySnapshot>(
stream: DatabaseMethods().getChatRoomMessages(chatRoomId),
builder: (context, AsyncSnapshot snapshot) { <<<< insert here
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data!.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
I found a solution:
StreamBuilder<QuerySnapshot>(
stream: DatabaseMethods().getChatRoomMessages(chatRoomId),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data!.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
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>
I tired to get data from firestore in flutter app.
This is my code
body: StreamBuilder(
stream:
FirebaseFirestore.instance.collection('my_contact').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
return ListView.builder(
itemCount: streamSnapshot.data.docs.length,
itemBuilder: (ctx, index) => SettingRowWidget(
"Call",
vPadding: 0,
showDivider: false,
onPressed: () {
Utility.launchURL((streamSnapshot.data.docs[index]['phone']));
},
),
);
},
));
and this code getting right data but problem is i'm getting error like this.
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#7adda):
The getter 'docs' was called on null.
Receiver: null
Tried calling: docs
I dont know how to solve it. Can anyone guide me to solve this?
Check if it's null while loading the data from firestore
StreamBuilder(
stream:
FirebaseFirestore.instance.collection('my_contact').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
if (!streamSnapshot.hasData) return Center();
if (streamSnapshot.data.docs.length!=0) {
return ListView.builder(
itemCount: streamSnapshot.data.docs.length,
itemBuilder: (ctx, index) => SettingRowWidget(
"Call",
vPadding: 0,
showDivider: false,
onPressed: () {
Utility.launchURL((streamSnapshot.data.docs[index]['phone']));
},
),
);
}else{
return Center(child:Text('No data found'));
}
},
));
After migrate to null-safety showing this error. What should I do now?
Widget chatMessages() {
return StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
itemCount: snapshot.data.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return chatMessageTitle(
ds["message"], myUserName == ds["sendBy"]);
})
: Center(child: CircularProgressIndicator());
});
}
After adding null check (!) showing this error <the getter 'docs' is not defined for the type of object>
itemCount: snapshot.data!.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data!.docs[index];
You have to cast snapshot.data to its type. Suppose the type is QuerySnapshot (change this with the actual type of snapshot.data).
(snapshot.data! as QuerySnapshot).docs.length
Instead of typecasting at all locations, we can specify the type of stream in the StreamBuilder.
StreamBuilder<QuerySnapshot>(
...
);
Now snapshot.data is inferred as QuerySnapshot and no typecast is required.
snapshot.data!.docs.length
I have solved mine by adding StreamBuilder and builder(context, AsyncSnapshot snapshot).
Widget chatMessages() {
return StreamBuilder<QuerySnapshot>(
stream: messageStream,
builder: (context, AsyncSnapshot snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
itemCount: snapshot.data.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return chatMessageTitle(
ds["message"], myUserName == ds["sendBy"]);
})
: Center(child: CircularProgressIndicator());
});
}
There are a few solutions:
Provide a type to your StreamBuilder:
StreamBuilder<QuerySnapshot> (...)
Provide a type to the second parameter of your builder:
builder: (context, QuerySnapshot snapshot)
Use as to downcast:
(snapshot.data! as QuerySnapshot).docs['key']
Add error and connection state checks like this:
Widget chatMessages() {
return StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
itemCount: snapshot.data.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return chatMessageTitle(
ds["message"], myUserName == ds["sendBy"]);
});
});
}