Reputation: 179
i have a list of events which i am pulling from firestore for a particular user id.
When user logouts and a different user logs in, i need stream to refresh and show appropriate events for the new user.
But list of events is not refreshed and it stills shows data of last user. I have to run "flutter run" again to show data for current user.
Please help.
String uida = FirebaseAuth.instance.currentUser!.uid;
class eventScreen extends StatelessWidget {
const eventScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final authService = Provider.of<AuthClass>(context);
final List storedocs = [];
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.logout),
tooltip: 'List of your activities',
onPressed: () {
authService.signout();
},
),
title: const Text('Activity list'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add),
tooltip: 'List of your events',
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => eventadd()),
);
},
),
],
),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('events')
.doc(uida)
.collection('events')
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
// final trip = event.fromSnapshot(document);
Map a = document.data() as Map<String, dynamic>;
storedocs.add(a);
a['id'] = document.id;
return Container(
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10)),
side: BorderSide(width: 3, color: Colors.blueAccent)),
child: ListTile(
onTap: () {
var docId = event.fromSnapshot(document);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
editevent(data: docId)));
},
leading: const Icon(Icons.description),
/* onPressed: (){
var docId = event.fromSnapshot(document);
Navigator.push(context, MaterialPageRoute(
builder: (context) => editevent(data: docId)));}*/
title: Text(a['title']),
trailing: IconButton(
icon: const Icon(Icons.edit),
onPressed: () {
var docId = event.fromSnapshot(document);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
editevent(data: docId)));
}),
/*ElevatedButton(
onPressed: (){
var docId = document.id;
Navigator.push(context, MaterialPageRoute(
builder: (context) => editevent(docId)));
}, child: Text('press'),
)*/
)));
}).toList(),
);
},
),
);
}
}
Upvotes: 2
Views: 541
Reputation: 7716
Looks like you're storing the user id in a global variable which will only store the value you give it in the first instance unless you actually call the change again.
Solution:
You should put the code to get the current user id in your widget so that it always gets the current value when the widget is shown.
class eventScreen extends StatelessWidget {
const eventScreen({Key? key}) : super(key: key);
String uida = FirebaseAuth.instance.currentUser!.uid; // Move this here
@override
Widget build(BuildContext context) {
...
}
}
Upvotes: 0
Reputation: 11984
You should not do this:
StreamBuilder(stream: FirebaseFirestore.instance.collection('events').doc(uida).collection('events').snapshots()
because you make a request with every rebuild. Depending on your widget structure, you may end up making hundreds of unnecessary requests and may have to pay a large Firebase bill. Instead you should create a Stream _stream;
field in your class, initialize it in initState()
as such:
_stream = FirebaseFirestore.instance.collection('events').doc(uida).collection('events').snapshots();
and use it as such
StreamBuilder(stream: _stream
Then, this gives you the chance to do this whenever you want to change the stream, for example when you change users:
setState(() {
_stream = FirebaseFirestore.instance.collection('events').doc(uida).collection('events').snapshots();
});
This way the stream will be renewed and you will see your screen use the new user's stream.
Upvotes: 1