I'm using flutter and managing data by cloud_firestore. I could send data to firestore, but now I'm Struggling with reading data.
In firestore, data are stored like this;
"users" collection -> "(uid)" document -> "userName" string field
And this is the code which I trying. Showing LinerProgressIndicator till snapshot has done.
CollectionReference users = FirebaseFirestore.instance.collection('users');
FutureBuilder(
future: users.doc().get(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox(
width: 50,
child: LinearProgressIndicator(),
);
}
if (snapshot.hasError) {
return SelectableText(snapshot.error.toString());
}
if (!snapshot.hasData) {
return const Text('No data found');
}
Map<String, dynamic> data =
snapshot.data!.data() as Map<String, dynamic>;
return Text("User Name: ${data['userName']}");
},
)
But when snapshot done, error occurred.
Expected a value of type 'Map<String, dynamic>', but got one of type 'Null'
I referenced One-time Read item
Addition 1:
I debugged builder
of FutureBuilder
.
print('${snapshot.data!.data()}');
null
print('${snapshot.data}');
Instance of '_JsonDocumentSnapshot'
Addition 2:
@Saiful Islam
I rewrote the code. Then other error occurred.
Expected a value of type 'Map<String, dynamic>', but got one of type '_JsonDocumentSnapshot'
Also, print()
result is same as Addition 1.
test code;
CollectionReference users = FirebaseFirestore.instance.collection('users');
FutureBuilder(
future: users.doc(FirebaseAuth.instance.currentUser!.uid).get(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
print('${snapshot.data!.data()}'); //null
print('${snapshot.data}'); //Instance of '_JsonDocumentSnapshot'
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox(
width: 50,
child: LinearProgressIndicator(),
);
}
if (snapshot.hasError) {
return SelectableText(snapshot.error.toString());
}
if (!snapshot.hasData) {
return const Text('No data found');
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data =
snapshot.data as Map<String, dynamic>;
return Text("User Name: ${data['username']}");
}
return const SelectableText("userName");
},
)
Addition 3:##
Added print('${jsonDecode(snapshot.data)}')
.
Error appears again.
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
Detail of the error;
Launching lib\main.dart on Chrome in debug mode...
This app is linked to the debug service: ws://127.0.0.1:59027/fBobSNPxOzo=/ws
Debug service listening on ws://127.0.0.1:59027/fBobSNPxOzo=/ws
Running with sound null safety
Connecting to VM Service at ws://127.0.0.1:59027/fBobSNPxOzo=/ws
════════ Exception caught by widgets library ═══════════════════════════════════
The following StateError was thrown building FutureBuilder<DocumentSnapshot<Object?>>(dirty, state: _FutureBuilderState<DocumentSnapshot<Object?>>#330c8):
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
The relevant error-causing widget was
FutureBuilder<DocumentSnapshot<Object?>> FutureBuilder:file:///D:/FlutterProjects/testProject/lib/profile.dart:32:13
When the exception was thrown, this was the stack
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw_
packages/cloud_firestore_platform_interface/src/platform_interface/platform_interface_document_snapshot.dart 77:7 get
packages/cloud_firestore/src/document_snapshot.dart 92:48 get
packages/cloud_firestore/src/document_snapshot.dart 96:40 _get
packages/testProject/profile.dart 50:45 <fn>
packages/flutter/src/widgets/async.dart 782:48 build
packages/flutter/src/widgets/framework.dart 4782:27 build
packages/flutter/src/widgets/framework.dart 4665:15 performRebuild
packages/flutter/src/widgets/framework.dart 4840:11 performRebuild
packages/flutter/src/widgets/framework.dart 4355:5 rebuild
packages/flutter/src/widgets/framework.dart 2620:31 buildScope
packages/flutter/src/widgets/binding.dart 882:9 drawFrame
packages/flutter/src/rendering/binding.dart 319:5 [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1143:15 [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1080:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 996:5 [_handleDrawFrame]
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 1003:13 invoke
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 157:5 invokeOnDrawFrame
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine.dart 440:45 <fn>
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════
A RenderFlex overflowed by 99340 pixels on the bottom.
The relevant error-causing widget was
Column Column:file:///D:/FlutterProjects/testProject/lib/profile.dart:26:20
════════════════════════════════════════════════════════════════════════════════
What kind of problem can you think of?
Thank you.
CodePudding user response:
You should only return Map of the document exists. However, you aren't checking if this condition is true or not.
To be safe, do not return data unless it's inside an if statement, which checks for hasData and then exists
.
The error is also probably due to a spelling mistake. Double check that again.
But your error is from the start, with this line:
future: users.doc().get(),
You did not tell which document. You need to pass the id
of the document when you run this query.
future: users.doc('0Cb43453fdsg4').get(), //This is an example 'id'.