Combine two Streams into one StreamProvider
So this seems to work fine:
StreamProvider<User>.value( value: auth.onAuthStateChanged.transform( FlatMapStreamTransformer<FirebaseUser, User>( (firebaseUser) => userService.streamUser(firebaseUser.uid), ), ),),
If anybody has doubts about this in certain edge cases, please let me know.
Maybe you can try this approach:
main.dart
void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider<FirebaseUser>( builder: (_) => FirebaseUser(), ), ], child: AuthWidgetBuilder(builder: (context, userSnapshot) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.indigo), home: AuthWidget(userSnapshot: userSnapshot), ); }), ); }}
AuthWidgetBuilder.dart
Used to create user-dependant objects that need to be accessible by all widgets. This widget should live above the [MaterialApp]. See [AuthWidget], a descendant widget that consumes the snapshot generated by this builder.
class AuthWidgetBuilder extends StatelessWidget { const AuthWidgetBuilder({Key key, @required this.builder}) : super(key: key); final Widget Function(BuildContext, AsyncSnapshot<User>) builder; @override Widget build(BuildContext context) { final authService = Provider.of<FirebaseUser>(context, listen: false); return StreamBuilder<User>( stream: authService.onAuthStateChanged, builder: (context, snapshot) { final User user = snapshot.data; if (user != null) { return MultiProvider( providers: [ Provider<User>.value(value: user), Provider<UserService>( builder: (_) => UserService(uid: user.uid), ), ], child: builder(context, snapshot), ); } return builder(context, snapshot); }, ); }}
AuthWidget.dart
Builds the signed-in or non signed-in UI, depending on the user snapshot. This widget should be below the [MaterialApp]. An [AuthWidgetBuilder] ancestor is required for this widget to work.
class AuthWidget extends StatelessWidget { const AuthWidget({Key key, @required this.userSnapshot}) : super(key: key); final AsyncSnapshot<User> userSnapshot; @override Widget build(BuildContext context) { if (userSnapshot.connectionState == ConnectionState.active) { return userSnapshot.hasData ? HomePage() : SignInPage(); } return Scaffold( body: Center( child: CircularProgressIndicator(), ), ); }}
This is originally from the tutorial of advance provider from Andrea Bizotto.But I tailored some the code according to your your code above.Hope this works, good luck!
Reference: https://www.youtube.com/watch?v=B0QX2woHxaU&list=PLNnAcB93JKV-IarNvMKJv85nmr5nyZis8&index=5