Flutter cubit blocprovider couldn't find the correct provider
I guess one needs to see your SignInPage code. Currently it seems your are missing the BlocBuilder as a child of BlocProvider.
In general your structure looks a bit - "mixed". Why do you use a BlocProvider as a child of a FutureBuilder? I would initialize the bloc which in turn initializes all necessary data and once ready yields the state to render the screen (and an activity indicator until then)
jdsflk
High school student, interested in Python, C++, Java and Flutter.
Updated on November 28, 2022Comments
-
jdsflk over 1 year
I am building a flutter app, in which the user can sign in with a google account. I'd like to manage this with cubit. I use Blocprovider to provide the cubit in the widget tree. The blocprovider is inside a futurebuilder in the runApp function. Here's my code:
The main.dart:home: FutureBuilder( future: initRepo.initialize(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return BlocProvider( create: (context) => SignInCubit(googleAuthRepo), child: SignInPage(googleAuthRepo, initRepo, databaseRepo)); } return SplashScreen(); }, ));
The SignInPage widget:
class SignInPage extends StatelessWidget { final GoogleAuthRepo _googleAuthRepo; final InitRepo initRepo; final DatabaseRepo _databaseRepo; SignInPage(this._googleAuthRepo, this.initRepo, this._databaseRepo); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.grey[900], Colors.grey[800]])), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image(image: AssetImage("lib/assets/icon.png")), BlocBuilder( builder: (context, state){ if(state is SignInInitial){ return buildInitial(); } else if(state is SignInLoading){ return buildLoading(); } else if(state is SignInLoaded){ return buildLoaded(); } return buildInvalidUser(); }, ) ], ), ); } Widget buildInitial() { return GoogleButton( this._databaseRepo, this.initRepo, this._googleAuthRepo); } Widget buildLoading() { return CircularProgressIndicator( valueColor: new AlwaysStoppedAnimation<Color>( Colors.blueGrey, ), ); } Widget buildInvalidUser() { return Column( children: [ GoogleButton(this._databaseRepo, this.initRepo, this._googleAuthRepo), Text( "Bejelentkezési hiba. Használj e5vos.hu-s e-mail címet!", //This is an error message, if the user doesn't use a specific email domain style: TextStyle(color: Colors.red), ) ], ); } Widget buildLoaded(){ return MainPage(_databaseRepo, initRepo); } }
The GoogleButton widget:
class GoogleButton extends StatefulWidget { @override _GoogleButtonState createState() => _GoogleButtonState(); final DatabaseRepo databaseRepo; final InitRepo initRepo; final GoogleAuthRepo _googleAuthRepo; GoogleButton(this.databaseRepo, this.initRepo, this._googleAuthRepo); } class _GoogleButtonState extends State<GoogleButton> { @override Widget build(BuildContext context) { return Center( child: Container( height: MediaQuery.of(context).size.height / 15, width: MediaQuery.of(context).size.width / 7, child: ButtonTheme( minWidth: 300, child: OutlineButton( borderSide: BorderSide(color: Colors.blueGrey, width: 1), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), onPressed: () async { final signInCubit = BlocProvider.of<SignInCubit>(context); signInCubit.signInWithGoogle(); }, child: Padding( padding: const EdgeInsets.fromLTRB(0, 10, 0, 10), child: Center( child: Text( 'Bejelentkezés', style: TextStyle( fontSize: 20, color: Colors.blueGrey, ), ), ), )), ), ), ); } }
When I run it, it throws the following error:
I tried to do what it recommends and swap the BlocProvider with Provider, so my code would look like this:
home: FutureBuilder( future: initRepo.initialize(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return Provider<SignInCubit>( create: (context) => SignInCubit(googleAuthRepo), builder: (context) { return SignInPage(googleAuthRepo, initRepo, databaseRepo) , },); } return SplashScreen(); }, ));
But then i get the argument type 'SignInPage Function(BuildContext)' can't be assigned to the parameter type 'Widget Function(BuildContext, Widget)' error.
-
jdsflk over 3 yearsThanks for your reply. I edited the question, which from now on contains the extra code.
-
w461 over 3 yearsyou should change your BlocBuilder statement to
BlocBuilder<MyBlocClass, MyBlocState>(builder: