I've been trying to retrieve user profiles to each user's account on sign in. Each user's information is stored in a doc with their respective uid's.
When a user registers and logs in, the data associated with the user displays correctly. However, when I create a second account and log in, the data associated with the second user displays for user 2 and user 1.
How do I dispose of the values in Streambuilder so each signed in user can see their profiles uniquely?
My code is below with a screenshot of my database
FirebaseAuth _auth = FirebaseAuth.instance;
final uid = _auth.currentUser!.uid;
final Stream<DocumentSnapshot<Map<String, dynamic>>> db = FirebaseFirestore
.instance
.collection('users')
.doc(uid)
.collection('Profile')
.doc('Personal details')
.snapshots();
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('First name'),
SizedBox(width: 40),
StreamBuilder<DocumentSnapshot>(
stream: db,
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError)
return Text('Something went wrong');
if (snapshot.connectionState ==
ConnectionState.waiting)
return CircularProgressIndicator();
dynamic data = snapshot.data!.data();
return Text(data['First name']);
// return Text('First name', style: boldFont);
},
),
]),
Divider(color: Colors.black),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Last name'),
SizedBox(width: 40),
StreamBuilder<DocumentSnapshot>(
stream: db,
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError)
return Text('Something went wrong');
if (snapshot.connectionState ==
ConnectionState.waiting)
return CircularProgressIndicator();
dynamic data = snapshot.data!.data();
return Text(data['Last name'], style: boldFont);
// return Text('Last name', style: boldFont);
},
),
],
),
My sign out code
onPressed: () async {
try {
await FirebaseAuth.instance.signOut();
errorMessage = '';
} on FirebaseAuthException catch (error) {
errorMessage = error.message!;
}
Navigator.of(context).pushReplacementNamed('/signIn');
setState(() {});
}
CodePudding user response:
I think will need StreamSubscription
to subscription event from Stream
.
When user signin success you will listent data on this subscription
. When user sign out, you will cancel
current subscription
.
Example:
_streamSubscriptionMessage = FirebaseDatabase.instance
.reference()
.child('users')
.child(sl.get<AuthCubit>().getUid().toString())
.child('badgeMessage')
.onValue
.map<int>((event) {
try {
return event.snapshot.value as int;
} catch (error) {
return 0;
}
})
CodePudding user response:
You can use StatefulWidget
, add a state variable to store current user, build using this, and apply setState
whenever Firebase Authentication state changes:
User? _currentUser; // define in the widget's state class.
@override Widget build(BuildContext context) {
if (_currentUser == null) {
// you can add something here
return;
}
final Stream<DocumentSnapshot<Map<String, dynamic>>> db =
FirebaseFirestore
.instance
.collection('users')
.doc(_currentUser.uid),
.collection('Profile')
.doc('Personal details')
.snapshots();
// rest of your build
}
And add this to you Firebase Authentication listener or create if you don't have yet:
FirebaseAuth.instance.authStateChanges().listen((User? firebaseUser) {
setState(() {
_currentUser = firebaseUser;
});
});
(It is a good idea to define this _currentUser
at the main application level, and use ChangeNotifierProvider
/ Consumer
/ context.read
etc.)