stream builder is not updating after navigation
Your conditional Is not being tested in the sub page. You should call Provider.of in the sectionWrapper() page.
You’re saying:
- if user is logged in, build sectionWrapper widget
- if user is not logged in build Authentication widget.
That is it for that build method. Once that is built, you need to say what you want to do next.
Eg. On the next screen, above your widget tree, set provider.of like you did. Then, if the value changes, provider will force a rebuild for that screen’s build method.
Ali Alqallaf
Updated on December 23, 2022Comments
-
Ali Alqallaf over 1 year
I am using a stream builder to detect if user logged in or not.
return StreamBuilder<User>( stream: AuthService().user, builder: (context, snapshot) { if (snapshot.hasData) return SectionWrapper(); else return Authentication(); });
and this is the stream I am using
Stream<User> get user { return _auth.onAuthStateChanged.map(_userFromFirebaseUser); } //create user object based on firebase user User _userFromFirebaseUser(FirebaseUser user) { return user != null ? User(uid: user.uid, email: user.email) : null; }
in the section wrapper, there are 2 buttons that navigates to two different sections of the app, when I use sign out method in one of these sections, the stream builder is not updating, and it requires refresh to update the state.
also i tried to put a button in section wrapper to sign out, it works and update UI before I navigate to one of the sections.
and this is the sectionWrapper() widget tree.
Column( children: <Widget>[ CupertinoButton( child: Text('Donation & Selling Section'), onPressed: () { Navigator.pushReplacementNamed( context, Section1.routeName, arguments: user); }), CupertinoButton( child: Text('Bookstores Section'), onPressed: () { Navigator.pushReplacementNamed( context, Section2.routeName); }), //works before navigation, does not work after navigation back here CupertinoButton( child: Text('Sign out'), onPressed: () async { await AuthService().signOut(); }), ], ),
I also tried to use stream provider with consumer and I ended with the same problem.
class Wrapper extends StatelessWidget { static const String routeName = '/'; @override Widget build(BuildContext context) { final user = Provider.of<User>(context); return user == null ? Authentication() : SectionWrapper(); } }
I wrapped material app with a stream provider.
MultiProvider( providers: [ StreamProvider<User>.value(value: AuthService().user), //other providers ], child: MaterialApp(
-
lenz over 3 yearsYou should probably use stream provider for this.
-
Ali Alqallaf over 3 yearsI tried and I kept getting the same result
-
lenz over 3 yearsStreambuilder has more boilerplate. You probably need to check for errors and connection state and such like this example from the docs. I’m not surprised this isn’t working.
-
lenz over 3 yearsStreamProvider will work 100%. I am doing the same thing. Are you placing the provider high enough in the widget tree? Could you share your code with streamProvider? And indicate where you put the provider?
-
Ali Alqallaf over 3 yearsI edited the question and share the code, i think it is high enough unless I should pass some data when navigate. Please take a look
-
lenz over 3 yearsAh I see what’s going on. You’re wanting the user to be redirected to Authentication() when they sign out from the SecrionWrapperscreen correct?
-
lenz over 3 yearsCheck out my answer, that should fix your issue. Please accept it if it helps. Or let me know if it doesnt
-
-
Ali Alqallaf over 3 yearsIt did work! I have been struggling for about 3 weeks, and you helped me. thank you so much I really appreciate it!
-
lenz over 3 yearsFantastic! I’m happy I could help, thanks for the message. Please upvote too :)
-
Ali Alqallaf over 3 yearswhen i tried your solution, it works fine, but when I sign in again with another user, i get back to the point where i logged out, the problem is when i make an action, all actions happen with the previous user despite the difference of the user id until i refresh the page using navigator or something to fetch data again, so is there any way to go to section wrapper when signing out so that when i sign back in, the section wrapper occurs and when I navigate to a section, data get fetched again
-
lenz over 3 yearsThat seems like a business logic issue my friend. It's hard to be more precise without seeing the rest of your code, but basically: provider will rebuild the page you're on when the user changes. So at the top of that page, withing your build method, you want to do the logic, i.e. if user is null go to Authentication. You might also want to revisit how you navigate between screens with Navigator.
-
lenz over 3 yearsUltimately, it is not the same issue. You should ask another question for this