I am building a Flutter app with multiple providers, and I encounter an error when trying to access my SignInProvider from the HomeScreen widget. The error message is:
Error: Could not find the correct Provider<SignInProvider> above this HomeScreen Widget
This issue occurs after adding a new provider in my app and trying to access it immediately. Here’s the relevant part of my code
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => SignInProvider(),
),
ChangeNotifierProvider(
create: (context) => InternetProvider(),
)
],
child: MaterialApp(
home: HomeScreen(),
),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final sp = context.watch<SignInProvider>();
return Scaffold(
// Scaffold details
);
}
}
class SignInProvider extends ChangeNotifier {
//instantiate of firebaseAuth, facebook and google
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
bool _isSignedIn = false;
bool get isSignedIn => _isSignedIn;
//hasError, errorCode, provider,uid,email,name,imageUrl
bool _hasError = false;
bool get hasError => _hasError;
String? _errorCode;
String? get errorCode => _errorCode;
String? _uid;
String? get uid => _uid;
String? _displayName;
String? get displayName => _displayName;
String? _email;
String? get email => _email;
SignInProvider() {
checkSignInUser();
}
Future checkSignInUser() async {
final SharedPreferences s = await SharedPreferences.getInstance();
_isSignedIn = s.getBool('signed_in') ?? false;
notifyListeners();
}
Future setSignIn() async {
final SharedPreferences s = await SharedPreferences.getInstance();
s.setBool('signed_in', true);
_isSignedIn = true;
notifyListeners();
}
// ENTRY FOR CLOUD_FIRESTORE
Future getUserDataFromFirestore(uid) async {
await FirebaseFirestore.instance
.collection('users')
.doc('uid')
.get()
.then((DocumentSnapshot snapshot) => {
_uid = snapshot['uid'],
_email = snapshot['email'],
_displayName = snapshot['displayName'],
});
notifyListeners();
}
Future saveDataToFirestore() async {
final DocumentReference r =
FirebaseFirestore.instance.collection('users').doc(uid);
await r.set({
'email': _email,
'uid': _uid,
'displayName': _displayName,
});
notifyListeners();
}
Future saveDataToSharedPreferences() async {
final SharedPreferences s = await SharedPreferences.getInstance();
await s.setString('email', _email!);
await s.setString('uid', _uid!);
await s.setString('displayName', _displayName!);
notifyListeners();
}
Future getDataFromSharedPreferences() async {
final SharedPreferences s = await SharedPreferences.getInstance();
_email = s.getString('email');
_uid = s.getString('uid');
_displayName = s.getString('displayName');
notifyListeners();
}
// checkUser exists or not in cloudfirestore
Future<bool> checkUserExists() async {
DocumentSnapshot snap =
await FirebaseFirestore.instance.collection('users').doc(_uid).get();
if (snap.exists) {
print('EXISTING USER');
return false;
} else {
print('NEW USER');
return false;
}
}
//signOut
Future userSignOut() async {
firebaseAuth.signOut;
await googleSignIn.signOut();
_isSignedIn = false;
notifyListeners();
//clear all storage information
clearStoredData();
}
Future clearStoredData() async {
final SharedPreferences s = await SharedPreferences.getInstance();
s.clear();
}
}
What could be causing this error, and how can I resolve it to ensure SignInProvider is correctly accessible in the HomeScreen widget?
2
Answers
I suggest using Consumer Instead of watch. This lets you wrap specific parts of the widget tree that depend on SignInProvider to rebuild when SignInProvider changes, without triggering the error.
Move your Providers up like this