The getter 'length' was called on snapshot's data - firebase

When the app starts it throws an Exception caught by widgets library in a console:
======== Exception caught by widgets library ======================================================= The following NoSuchMethodError was thrown building
StreamBuilder<List<Entry>>(dirty, state:
_StreamBuilderBaseState<List<Entry>, AsyncSnapshot<List<Entry>>>#97504): The getter 'length' was called on
null. Receiver: null Tried calling: length on `itemCount: snapshot.data.length`,
But the whole app nonetheless works in emulator. What is the reason of that?
StreamBuilder<List<Entry>>(
stream: entryProvider.entries,
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data.length, // the error is here
itemBuilder: (context, index) { ...

When the stream is busy loading data, snapshot.data will be null until the ConnectionState of StreamBuilder is ConnectionState.done.
There are a few fixes you can try.
1. Use if (snapshot.hasData)
This will ensure that snapshot.data is used only when it is not null
2. Use Null operator
When trying to get the length of snapshot.data, try this
snapshot?.data.length ?? 0
3. Check ConnectionState
You can also check the ConnectionState of StreamBuilder but you might still need to use the first solution i.e, snapshot.hasData, normally I
would prefer one of the above solutions.

Use snapshot.data.size instead of .length.

solved the problem by replacing StreamBuilder<Object> with StreamBuilder<QuerySnapshot>. by default the StreamBuilder comes in this form StreamBuilder<Object>
this will work 100%

Related

Flutter SteamBuilder throwing error on first argument context

I have a problem here with flutter (v2.8.1) on my windows.
I am trying to use StreamBuilder class to fetch data from firebase but it is not working anyhow. I tried to use BuildContext context but it is still throwing me error on context.
Please have a look at my code and let me know what I am doing wrong. Answers are appreciated. Thanks in advance.
StreamBuilder(builder: (BuildContext context, snapshot), stream: _firestore.collection('messages').snapshots()),
Error :
The argument type 'Type' can't be assigned to the parameter type 'Widget Function(BuildContext, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>)'.
Please check the image : https://imgur.com/a/QJs6hS9
The builder argument should be a function that returns a widget.
builder: (context, snapshot) {
// return a widget that uses the snapshot
// for example
return Text(snapshot.data().title);
}

The argument type 'User?' can't be assigned to the parameter type 'Future<Object?>?'

With reference to the recent changes regarding FirebaseUser to User. FirebaseAuth.instance.currentUser() is not found at all (while throughing error "The expression doesn't evaluate to a function, so it can't be invoked." The solution to that however was to simply remove the paranthesis as FirebaseAuth.instance.currentUser. But now we have another error that it isn't a future type i.e "The argument type User can't be assigned to the parameter type Future<Object?>?". Following is my code block.
return FutureBuilder(
future: FirebaseAuth.instance.currentUser,
builder: (ctx, futureSnapshot) => ListView.builder(
reverse: true, // So that 1st message goes to last.
itemCount: chatDocument.length,
itemBuilder: (ctx, index) => MessageBubble(
message: chatDocument[index]['text'],
isMe: chatDocument[index]['userId'],
),
),
);
In the above code block I intend to provide future to my `FutureBuilder`. In summary previously `FirebaseUser` object did return a future, but probably `User` doesn't anymore. How may I handle this case? Thanks in advance.
I don't typically do that with a FutureBuilder. Once you have a user, you don't need to async it.
final FirebaseAuth_auth = FirebaseAuth.instance();
final User? user;
user = _auth.currentUser;
Then, if user != null ....create your ListView else, return a CircularProgressIndicator or whatever.
Look up Net Ninja for some nice videos for getting yourself set up with all that, just having a stream based on userChanges() for your project. More robust setup.

FutureBuilder The method '[]' was called on null. Receiver: null

Im getting this error in my dart code. If I delete coverImage widget , It gives error for other snapshat.data`s widget
My Error
Exception caught by widgets library
The following NoSuchMethodError was thrown building FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(dirty, state:
_FutureBuilderState<DocumentSnapshot<Map<String, dynamic>>>#45e11):
The method '[]' was called on null.
Receiver: null
Tried calling:
The way Im using data.
image: DecorationImage(
fit: BoxFit.cover,
image: (snapshot.data['coverImage']).isEmpty
? AssetImage('assets/background.png')
: NetworkImage(snapshot.data['coverImage']),
),
My flutter doctor
Hi in your switch statement you are not doing anything, so you are not filtering in which state the futurebuilder is and thus trying to access the data when its not already completed:
return FutureBuilder(builder: ( context, snapshot) {
if(snapshot.hasData){
return ListView();
}else if (snapshot.hasError){
return Center(child:Text(snapshot.error.toString()));
}
return Center(child: CircularProgressIndicator());
}
Here the three principal states are taken care of.
It's probably your snapshot data is null
Maybe you should handle it with ? or == null
image: (snapshot?.data['coverImage']).isEmpty
or
final dataCoverImage = snapshot.data['coverImage']
image: (dataCoverImage == null) || (dataCoverImage.isEmpty)
? AssetImage('assets/background.png')
: NetworkImage(snapshot.data['coverImage']),
check if ['coverImage'] is there in your database your error shows that this field is not in your database
you can check in the code by
(snapshot.data['coverImage']).isEmpty || snapshot.data['coverImage'] ==null)

Not getting data in latest firestore flutter library

While implementing the latest firestore library for flutter project, I am getting the the below error
Bad state: field does not exist within the DocumentSnapshotPlatform
CODE IMPLEMENTED
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index){
String itemTitle = snapshot.data.docs[index]['postContent'];
return ContentList(postContent: postContent);
});
Please guide me how to resolve, I am using Firestore ^0.14.3 dependency
The error is on this line String itemTitle = snapshot.data.docs[index]['postContent']; where Flutter tries to look for an item in the map with the key of 'postContent' but it is not found.
It is up to you to figure out why this so but I would also like refrain against asking questions which have already been asked. Next time just a tip, paste the error into Google and review the top links. :)
Below is a duplicate:
https://github.com/FirebaseExtended/flutterfire/issues/3826

Build Error in Dart / Flutter during build

So in my build function, I load my user data, and once it is loaded I would like to change the theme of the app (which calls setState()). The issue is that I can't call setState during the build process, like the error below states. How would I go about loading a user selected theme on app startup? Also, is it not recommended to be loading data inside the build function? It seems to work well but feels kinda gross. Thanks!
Widget build(BuildContext context) {
//get user object from Firebase
//once user is loaded, take their chosen color theme and call updateTheme()
}
Error:
This ThemeSwitcherWidget widget cannot be marked as needing to build because the framework is
I/flutter (23889): already in the process of building widgets. A widget can be marked as needing to be built during the
I/flutter (23889): build phase only if one of its ancestors is currently building. This exception is allowed because
I/flutter (23889): the framework builds parent widgets before children, which means a dirty descendant will always be
For loading data or doing a blocking call, you should use FutureBuilder or StreamBuilder (I am not much aware of firebase APIs so can't tell which one to use, but both of them are very similar.) It takes a future or stream as an argument and builds based on it. I am assuming you know about future API of dart
Here is some example code that will give you some idea.
StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return new SplashScreen();
} else {
if (snapshot.hasData) {
return new MainScreen(firestore: firestore, uuid: snapshot.data.uid);
}
return new LoginScreen();
}
}
)

Resources