Flutter cubit blocprovider couldn't find the correct provider

856

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)

Share:
856
jdsflk
Author by

jdsflk

High school student, interested in Python, C++, Java and Flutter.

Updated on November 28, 2022

Comments

  • jdsflk
    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: error picture

    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
    jdsflk over 3 years
    Thanks for your reply. I edited the question, which from now on contains the extra code.
  • w461
    w461 over 3 years
    you should change your BlocBuilder statement to BlocBuilder<MyBlocClass, MyBlocState>(builder: