I am trying to use bloc in my code for firestore database
HandleSubscription method
void handleSubscription() {
context.read<SubscriptionBloc>().saveNewSubscription("123", "abc");
}
Widget build:
@override
Widget build(BuildContext context) {
handleSubscription();
return Scaffold(
...
);
}
I have SubscriptionBloc code but I don’t want to share as my problem is not related with this code.
I am getting this error:
Exception has occurred. ProviderNotFoundException (Error: Could not
find the correct Provider above this ArticleDetails
WidgetThis happens because you used a
BuildContext
that does not include
the provider of your choice. There are a few common scenarios:
You added a new provider in your
main.dart
and performed a hot-reload. To fix, perform a hot-restart.The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route,
then other routes will not be able to access that provider.You used a
BuildContext
that is an ancestor of the provider you are trying to read.Make sure that ArticleDetails is under your
MultiProvider/Provider. This usually happens when
you are creating a provider and trying to read it immediately.For example, instead of:
return Provider<Example>( create: (_) => Example(), // Will throw a ProviderNotFoundError, because `context` is associated // to the widget that is the parent of `Provider<Example>` child: Text(context.watch<Example>().toString()), ); } ``` consider using `builder` like so: ``` Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // we use `builder` to obtain a new `BuildContext` that has access to the provider builder: (context, child) { // No longer throws return Text(context.watch<Example>().toString()); } ); } ```
If none of these solutions work, consider asking for help on
StackOverflow: https://stackoverflow.com/questions/tagged/flutter )
2
Answers
Make sure that the
BuildContext
used inhandleSubscription()
actually has access toSubscriptionBloc
.I.e., you are trying to read a provider as soon as the widget builds. Consider deferring this to a later lifecycle method like
didChangeDependencies
or utilize aBuilder
widget to make sure the context you are using is a descendant of your provider.Builder
approach:That
Builder
would create a newBuildContext
that is a direct child ofScaffold
, which should ideally be under yourProvider<SubscriptionBloc>
if you have structured your widget tree correctly.didChangeDependencies
method approach:That method is called when a dependency of the
State
object changes.In your case, if your widget relies on an
InheritedWidget
(which is whatProvider
uses under the hood),didChangeDependencies
is called whenever that inherited widget is updated.The
handleSubscription
method is moved intodidChangeDependencies
.The
Provider.of<SubscriptionBloc>(context, listen: false)
call fetches theSubscriptionBloc
from the nearest ancestor in the widget tree. SincedidChangeDependencies
is called afterinitState
and every time the widget rebuilds due to a change in anInheritedWidget
, it is generally a safe place to access yourProvider
.That approach avoids accessing the
Provider
directly within thebuild
method, giving the widget a chance to complete its initial build process.the error says the provider not found means you haven’t provided the provider above the widget
Suppose your widget/screen is
ArticleDetails
in which you’re callinghandleSubscription
method, so what have you to do is wrap yourArticleDetails Widget/Screen
withBlocProvider
which will provide the scope ofSubscriptionBloc
toArticleDetails
. For exampleAnd the Article widget is