I am attempting to make an app and I wanted to use a Bloc provider to store a user's data when they create their account. I have the Firebase collection created with the fields already defined; however, when I attempt to run it in Flutter, I get a huge error. It essentially says that it cannot find the correct provider form my bloc. I'm not sure how to fix this error, so I would really appreciate some guidance :). I have attached a screenshot of the emulator screen with the error and possible reasons for the error, as well as my code:
Onboarding bloc code:
part 'onboarding_event.dart';
part 'onboarding_state.dart';
class OnboardingBloc extends Bloc<OnboardingEvent, OnboardingState> {
final DatabaseRepository _databaseRepository;
final StorageRepository _storageRepository;
OnboardingBloc({
required DatabaseRepository databaseRepository,
required StorageRepository storageRepository,
}) :
_databaseRepository = databaseRepository,
_storageRepository = storageRepository,
super(OnboardingLoading()) {
on<StartOnboarding>(_onStartOnboarding);
on<UpdateUser>(_onUpdateUser);
on<UpdateUserImage>(_onUpdateUserImage);
}
Future<void> _onStartOnboarding(
StartOnboarding event,
Emitter<OnboardingState> emit)
async {
User user = User(
id: '',
name: '',
birthdate: '',
imageUrls: [],
Goals: '',
Interests: [],
Focus: []);
String documentId = await _databaseRepository.createUser(user);
emit(OnboardingLoaded(user: user.copyWith(id: documentId)));
}
void _onUpdateUser(
UpdateUser event,
Emitter<OnboardingState> emit) {
if (state is OnboardingLoaded) {
_databaseRepository.UpdateUser(event.user);
emit(OnboardingLoaded(user: event.user));
}
}
void _onUpdateUserImage(
UpdateUserImage event,
Emitter<OnboardingState> emit)
async{
if (state is OnboardingLoaded) {
User user = (state as OnboardingLoaded).user;
await _storageRepository.uploadImage(user, event.image);
_databaseRepository.getUser(user.id!).listen((user) {
add(UpdateUser(user: user));
});
}
}
}
Account Onboarding Screen (where I mention the specific bloc):
class AccountOnboarding extends StatefulWidget {
const AccountOnboarding({Key? key}) : super(key: key);
static const String routeName = '/profile onboarding';
static Route route() {
return MaterialPageRoute(
settings: const RouteSettings(name: routeName),
builder: (context) => MultiBlocProvider(
providers: [BlocProvider<OnboardingBloc>(
create: (_) => OnboardingBloc(
databaseRepository: DatabaseRepository(),
storageRepository: StorageRepository())
..add(StartOnboarding()),
)],
child: const AccountOnboarding()));
}
@override
State<AccountOnboarding> createState() => _AccountOnboardingState();
}
class _AccountOnboardingState extends State<AccountOnboarding> {
static const List<Tab> tabs = <Tab>[
Tab(text: 'Name'),
Tab(text: 'Age and Profile'),
Tab(text: 'Bio and Interests'),
Tab(text: 'Selection')
];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: tabs.length,
child: Builder(builder: (BuildContext context) {
final TabController tabController = DefaultTabController.of(context)!;
tabController.addListener(() {
if (!tabController.indexIsChanging) {}
});
return BlocBuilder<OnboardingBloc, OnboardingState>(
builder: (context, state) {
if (state is OnboardingLoading) {
return
const Center(child: CircularProgressIndicator());
}
if (state is OnboardingLoaded) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
title: Row(
children: [
Expanded(
child: Image.asset('assets/images/Logo_Strength.png',
height: 50),
),
Expanded(
flex: 2,
child: RichText(
text: TextSpan(
style: GoogleFonts.montserrat(
fontSize: 30),
children: <TextSpan> [
TextSpan(text: 'Stren',
style: GoogleFonts.montserrat(
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
])),
TextSpan(text: ';',
style: GoogleFonts.montserrat(
color: const Color(0xffef6a7a), fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
])),
TextSpan(text: 'th',
style: GoogleFonts.montserrat(
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
]))
],
),
),
),
],
)
),
body: TabBarView(
// physics: const NeverScrollableScrollPhysics(),
children: [
NamePage(tabController: tabController,),
ageAndPicture(tabController: tabController,),
bioAndInterests(tabController: tabController,),
SelectionPage(tabController: tabController,)
],
),
);
}
else {return
const Text('Something went wrong.');
}
}
);
}));
}}
Main dart:
int? isViewed;
Future <void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await FirebaseAppCheck.instance.activate();
final prefs = await SharedPreferences.getInstance();
final showLogin = prefs.getBool('showLogin') ?? false;
Paint.enableDithering = true;
// This is for our onboarding screen
isViewed = prefs.getInt('onboard');
runApp(MyApp(showLogin: showLogin));
}
class MyApp extends StatelessWidget {
final bool showLogin;
const MyApp({Key? key,
required this.showLogin}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Strength',
debugShowCheckedModeBanner: false,
home: AccountOnboarding() // FINAL SCREEN IS SPLASH SCREEN
);
}
}
Try to add provider on main.dart. It can be on Material home:
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => OnboardingBloc ()
),
),
],
child: const AccountOnboarding(),
);
}
class MyApp extends StatelessWidget {
final bool showLogin;
const MyApp({Key? key, required this.showLogin}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Strength',
debugShowCheckedModeBanner: false,
home: MultiBlocProvider(
child: AccountOnboarding(),
providers: [
BlocProvider(
create: (context) => OnboardingBloc(),
)
],
),
);
}
}
More about flutter bloc