Fetching data properly with Futurebuilder and json response - flutter

How can I render my response in my text widget?
My json snapshot.data is as following:
"{\"0\":{\"Breed\":\"American Hairless Terrier\",\"count\":1},\"1\":{\"Breed\":\"Bolognese\",\"count\":2},\"2\":{\"Breed\":\"Cavalier King Charles Spaniel\",\"count\":12},\"3\":{\"Breed\":\"Central Asian Shepherd Dog\",\"count\":1},\"4\":{\"Breed\":\"Papillon\",\"count\":1}}"
I tried to display my data like this:
Text(snapshot.data[index.toString()]['Breed']),
but I am getting:
type 'String' is not a subtype of type 'int' of 'index'

try this, might not be perfect but i will give you some idea, the error is because you are assigning int value to Text widget
Text((snapshot.data[index].
['Breed']).toString());
if you want to show it in
futureBuilder and listview
here:
FutureBuilder(
future: FirebaseFirestore.
instance.
collection("groups").
doc(groupId).snapshots(),
//here your collection name
// and doc id
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return Text("Loading");
}
var userDocument = snapshot.data["Breeds"];
return ListView.builder(
itemCount: userDocument.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Text(userDocument[index]);
),
}
);

The indices 0,1,2,3.. are strings(wrapped with quotation marks). But you are providing int.
Try
Text(snapshot.data['Breed'][index.toString()])

Related

uid is not defined for type 'Object' in flutter

i am trying to check if a user id is the same as the current user's id by using data.uid but i keep getting this error:
The getter 'uid' isn't defined for the type 'Object'.
this is the code
Widget build(BuildContext context) {
return FutureBuilder(
future: Future.value(FirebaseAuth.instance.currentUser),
builder: (context, futureSnapshot){
if(futureSnapshot.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator(),);
}
return StreamBuilder <QuerySnapshot>(
stream: firestore.collection('chats').orderBy('timeStamp', descending: true).snapshots(),
builder:(ctx, chatSnapshot){
if(chatSnapshot.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator(),);
}
final chatdocs = chatSnapshot.data!.docs;
return ListView.builder(
reverse: true,
itemCount: chatdocs.length ,
itemBuilder: (ctx, index) => messageBubble(
chatdocs[index]['text'],
chatdocs[index]['userId'] == futureSnapshot.data!.uid, //this is the error
)
);
}
);
} );
Since you don't declare the type of the Future in your FutureBuilder, it resolves to an Object. And an Object doesn't have a uid property, which is why you get the error.
To solve this declare the type of your FutureBuilder, which in your case would be:
return FutureBuilder<User>(
Note that I have no idea why you're using a FutureBuilder here to begin with. The FirebaseAuth.instance.currentUser is a synchronous value, so you don't need a FutureBuilder to access it. Removing the FutureBuilder would lead to the exact same result.
If you're trying to make your code respond to auth state changes, like that it takes a moment for Firebase to restore the user's sign-in state when you start the app, you'll want to actually listen to authStateChanges with a StreamBuilder for that nowadays, as shown in the first code snippet in the documentation on getting the current user. Here too, you'll want to declare your StreamBuilder with a User type, just like we did above for the FutureBuilder.
You can try json decoding your variable into the object User you are looking for:
If the futureSnapshot.data is a user you'll be able to use the uid as a map key to check with chatdocs[index]['userId']
Like this:
import 'dart:convert';
final Map<String, dynamic> _valueMap = json.decode(futureSnapshot.data!);
chatdocs[index]['userId'] == _valueMap['uid'];
Try the following code:
StreamBuilder<QuerySnapshot>(
stream: firestore.collection('chats').orderBy('timeStamp', descending: true).snapshots(),
builder: (ctx, chatSnapshot) {
if (chatSnapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
final List<QueryDocumentSnapshot<Object?>> chatdocs = chatSnapshot.data!.docs;
final String uid = FirebaseAuth.instance.currentUser?.uid ?? '';
return ListView.builder(
reverse: true,
itemCount: chatdocs.length,
itemBuilder: (ctx, index) {
final Map<String, dynamic> chat = (chatdocs[index]).data() as Map<String, dynamic>;
return messageBubble(
chat['text'],
chat['userId'] == uid,
);
},
);
},
),

Flutter Firestore QuerySnapshot has no instance of getter 'documentID'

I get an error that "QuerySnapshot that has no instance of getter 'documentID'".
StreamBuilder(
stream: FirebaseFirestore.instance.collection("CHAT").orderBy("createdAt",descending: true).snapshots(),
builder: (ctx,AsyncSnapshot snapshot){
if(snapshot.connectionState==ConnectionState.waiting)
{
return Center(child: CircularProgressIndicator(color:Colors.green[300]));
}
else {
var doc=snapshot.data!.docs;
var user=FirebaseAuth.instance.currentUser;
return ListView.builder(
reverse: true,
itemCount: doc.length,
itemBuilder: (BuildContext ctx,index){
return BubbleMessage(
key: ValueKey(doc[index].documentID),
//:::::::::::::::get Message From firebase :::::::::::
message:doc[index]['message'],
//we check if the id isMe or the Other Person
isMe: doc[index]['userId']==user!.uid,
//::::::::::::::get username From Firebase ::::::::::::::::::
username: doc[index]['username'],
);
},
);
Why am I unable to access the documentID?
The getter of the ID is just .id, not .documentID. See here. I'd recommend using your IDE's autocomplete to see what getters are available.
In the majority of cases the documentation on Flutter packages are extremely well documented and visible from within your IDE.

Why am I getting this error Bad state: field does not exist within the DocumentSnapshotPlatform while using firestore?

Bad state: field does not exist within the DocumentSnapshotPlatform
The relevant error-causing widget was
StreamBuilder<QuerySnapshot<Object?>>
StreamBuilder:file:///D:/EgoPro/Flutter%20Apps/task_app/lib/screens/task_screen.dart:189:13
this is the error
StreamBuilder<QuerySnapshot>(
// <2> Pass `Stream<QuerySnapshot>` to stream
stream:
FirebaseFirestore.instance.collection('tasks').snapshots(),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
// <3> Retrieve `List<DocumentSnapshot>` from snapshot
final List<DocumentSnapshot> documents = snapshot.data!.docs;
print(documents);
return ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: documents
.map(
(doc) => Meetingcard(
id: doc.get("id"),
title: doc.get("title"),
description: doc.get("description"),
time: TimeOfDay.now()),
)
.toList());
} else if (snapshot.hasError) {
return Text("'It's Error!'");
} else {
return CircularProgressIndicator();
}
},
)
Why am i getting this error ?
This is the image of my documents
enter image description here>
doc.get will return this error if the specified field does not exists in the document. So one of your fields: id, title, description (or more of these) can't be found in doc.
You can add a breakpoint or log and check the result of doc.data() inside your .map((doc)... to see what does it contain.
(One of the possible ways to handle optional fields is to define a model class, create converter where you handle missing values and assign empty string or other default value, so when you read data from your stream you can use this model, and you don't have to handle missing values there.)
EDIT:
Based on the error picture in comment the error seems to be somewhere else, where you assign value to documents. snapshot.data!.docs has the type List<QueryDocumentSnapshot<Object?>> and not `List. Try the following code:
StreamBuilder<QuerySnapshot>(
// <2> Pass `Stream<QuerySnapshot>` to stream
stream:
FirebaseFirestore.instance.collection('tasks').snapshots(),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
// <3> Retrieve `List<DocumentSnapshot>` from snapshot
return ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: snapshot.data!.docs
.map(
(DocumentSnapshot doc) => Meetingcard(
id: doc.data()!["id"],
title: doc.data()!["title"],
description: data()!["description"],
time: TimeOfDay.now()),
)
.toList());
} else if (snapshot.hasError) {
return Text("'It's Error!'");
} else {
return CircularProgressIndicator();
}
},
)

Errors when trying to use ValueListenableBuilder

I am trying update a list with the changes in current but ValueListenableBuilder is giving errors
ValueListenableBuilder(
valueListenable: currentColor,
builder: (BuildContext context, String current, Widget child) {
child: PaginateFirestore(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilderType: PaginateBuilderType.listView,
itemBuilder: (index, context, documentSnapshot) {
final data = documentSnapshot.data() as Map?;
return MainComponent(
title: data == null ? 'Error' : data['id']);
},
// orderBy is compulsory to enable pagination
query: FirebaseFirestore.instance
.collection('transfer')
.orderBy('id', descending: decen),
// to fetch real-time data
isLive: true,
);
}),
Error:
The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type.
The argument type 'Widget Function(BuildContext, String, Widget)' can't be assigned to the parameter type 'Widget Function(BuildContext, String, Widget?)'
The builder parameter is a function that returns a Widget and not a Widget, so you cant use child here.
Update the builder function and add return in the place where child is used.
The second error is a type mismatch, update the builder line and add a ? after widget, the line should read.
builder: (BuildContext context, String current, Widget? child)

AsyncSnapshot rejecting Type Annotation

I have a StreamBuilder that is taking data from my bloc component.
However it keeps rejecting my type annotation AsyncSnapshot<List<int>> snapshot and only accepts dynamic as a type AsyncSnapshot<List<dynamic>> snapshot. Yet in the examples i've viewed they do have type annotaions with no complaints.
Here is my stream creation.
Widget buildList(StoriesBloc bloc) {
return StreamBuilder(
stream: bloc.topIds,
builder: (BuildContext context, AsyncSnapshot<List<int>> snapshot) {
if (!snapshot.hasData) {
return Text("Still Waiting for Ids to fetch");
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, int index) {
return Text('${snapshot.data[index]}');
},
);
},
);
}
Here is the VSCode error generated.
What could i be doing wrong ?
Turns out my bloc.topIds result type was not of type List<int>.
Observable<List> get topIds => _topIds.stream;
So i simply changed it to fulfill the required type.
Observable<List<int>> get topIds => _topIds.stream;
And that fixed the issue. Hope it helps someone else.