I'm making a Flutter application and I'm trying to get the user's data in the app.
So basically, the user registers with his info (name, email, password), and this data is displayed in a ProfilePage
when he's logged in.
According to Firestore documentation, I'm supposed to use a StreamBuilder
to get his data.
At this point, everything works fine.
The problem is that when the user logs out and another user logs in, the ProfilePage
displays the precedent user's data (the user logged out).
Only if I restart the app, then I'm getting the right data.
Here's my ProfilePage
:
class UserInformation extends StatefulWidget {
@override
_UserInformationState createState() => _UserInformationState();
}
class _UserInformationState extends State<UserInformation> {
final _uid = FirebaseAuth.instance.currentUser!.uid;
final Stream<QuerySnapshot> _usersStream =
FirebaseFirestore.instance.collection('Users')
.doc(_uid)
.collection('UserData')
.snapshots();
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
key: Key(_uid),
stream: _usersStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
}
return ListView(
children: snapshot.data!.docs
.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['full_name']),
subtitle: Text(data['company']),
);
})
.toList()
.cast(),
);
},
);
}
}
I see that this is a question asked several times on SO but I couldn't find a good solution. I tried to add a unique key in the StreamBuilder
but it doesn't solve the problem.
I also saw the use of didUpdateWidget
but I don't understand how to use it.
CodePudding user response:
try replace this:
final _uid = FirebaseAuth.instance.currentUser!.uid;
with this:
late final _uid;
@override
initState() {
_uid = FirebaseAuth.instance.currentUser!.uid;
super.initState();
}
then restart your app again, and simulate your behavior
CodePudding user response:
reload the current user details with:
await FirebaseAuth.instance.currentUser!.reload();
I will say that the best place to put it, is to do it before returning that stream, first make the Stream a method:
Stream<QuerySnapshot> myStream() async {
await FirebaseAuth.instance.currentUser!.reload();
final _uid = FirebaseAuth.instance.currentUser!.uid;
return FirebaseFirestore.instance.collection('Users')
.doc(_uid)
.collection('UserData')
.snapshots();
}
then in the StreamBuilder
, set stream
property to:
stream: myStream(),