Issue
CollectionReference users = FirebaseFirestore.instance.collection('Users');
FirebaseAuth auth = FirebaseAuth.instance;
String uid = FirebaseAuth.instance.currentUser!.uid.toString();
var userData;
var dbFuture;
@override
void initState() {
dbFuture = getData();
super.initState();
}
Future getData() async {
final String uid = FirebaseAuth.instance.currentUser!.uid.toString();
final DocumentSnapshot doc = await users.doc(uid).get();
users.doc(uid).get().then((DocumentSnapshot doc) {
userData = doc.data();
print(doc.data());
});
}
@override
Widget build(BuildContext context) => Scaffold(
body: FutureBuilder(
future: dbFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Container(
child: Text('waiting'),
);
}
if (!snapshot.hasData) {
return Container(
child: Text('error'),
);
}
final data = snapshot.data;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(userData['displayName']),
ElevatedButton(
onPressed: FirebaseAuth.instance.signOut,
child: Text("Log out"))
],
),
);
}),
);
I'm new in Flutter and trying to make an application for managing an academy.
I successfully saved the data at Firestore Cloud, and I can read them with
print(doc.data());
Now I want to build Profile page with those data, so I used Futurebuilder.
But snapshot always has no data.
I read documents as well, but still have no idea.
Solution
To get your data from Firebase and display them in your widgets, you have two ways, but you have to choose only one according to your needs.
With FutureBuilder()
This code will call your database and load the info you request at each build and at each setState()
(responsible for updating your interface content). It could be useful for some data types, but in your case your redundant Firebase calls could cost you.
CollectionReference users = FirebaseFirestore.instance.collection('Users');
final auth = FirebaseAuth.instance;
late final uid = auth.currentUser!.uid;
@override
Widget build(BuildContext context) => Scaffold(
body: FutureBuilder(
future: users.doc(uid).get(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Container(
child: Text('waiting'),
);
}
if (!snapshot.hasData) {
return Container(
child: Text('error'),
);
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(snapshot.data!['some_data']),
Text(auth.currentUser?.displayName ?? 'user have no name'),
ElevatedButton(
onPressed: auth.signOut,
child: Text("Log out"))
],
),
);
}),
);
In the initState()
When using initState()
, the code inside is called only once. To refresh the content, you will have to call getData()
manually (in a setState()
for example)
CollectionReference users = FirebaseFirestore.instance.collection('Users');
final auth = FirebaseAuth.instance;
late final uid = auth.currentUser!.uid;
String? someData;
@override
void initState() {
getData();
super.initState();
}
Future<void> getData() async {
users.doc(uid).get().then((doc) {
someData = doc['some_data'];
});
}
@override
Widget build(BuildContext context) => Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(someData ?? 'no data'),
Text(auth.currentUser?.displayName ?? 'user have no name'),
ElevatedButton(
onPressed: auth.signOut,
child: Text("Log out"))
],
),
),
);
Finally, if your users authenticate, you can use auth.currentUser?.displayName
and auth.currentUser!.updateDisplayName('new name')
to simply get and change your users' names.
Answered By - Matt
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.