I am new to flutter and I have been trying to create an app that requires authentication. After getting the user ID and basic information, I check for the role of the user and once that is done, I send the user to the home page. I tried to send the user to home using SchedulerBinding.instance!.addPostFrameCallback((_) { Navigator.of(context).pushReplacementNamed('/');}); but I get:
Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
Here is my code (In my provider class):
Future<void> getUserRole(BuildContext context, String? userID) async {
try {
if (userID != null) {
print('initialized');
initialized = true;
print('Getting role of user wirh ID: $userID');
var doc = await databaseReference.collection('Users').doc(userID).get();
if (doc.exists) {
Map<String, dynamic> data = doc.data()!;
campusID = data['campusID'];
firstName = data['firstName'];
lastName = data['lastName'];
exams = data['auth'];
if (data['role'] == 'Admin') {
print('Found admin');
isAdmin = true;
} else if (data['role'] == 'Faculty') {
print('Found faculty');
isTeacher = true;
} else {
print('Found student');
}
login = true;
print('login!');
} else {
//Create new user
uuid = userID;
print('Adding new user...');
SchedulerBinding.instance!.addPostFrameCallback((_) {
Navigator.of(context).pushReplacementNamed('/register');
});
}
}
} catch (err) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
backgroundColor: Colors.red,
behavior: SnackBarBehavior.floating,
content: Text('Error: $err')));
print('Could not get user roles: $err');
} finally {
print('Noti');
notifyListeners();
}}
Here is my home page:
class ScanPage extends StatelessWidget {
ScanPage({Key? key}) : super(key: key);
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
UserProvider userProvider = Provider.of<UserProvider>(context);
if (userProvider.user == null) {
SchedulerBinding.instance!.addPostFrameCallback((_) {
userProvider.getUser(context);
});
print('Getting user');
} else if (!userProvider.initialized) {
SchedulerBinding.instance!.addPostFrameCallback((_) {
userProvider.getUserRole(context, userProvider.user!.uid);
});
print('Getting user role');
}
if (userProvider.user?.displayName == null || !userProvider.initialized) {
return Scaffold(
backgroundColor: Colors.grey[300],
key: _scaffoldKey,
body: const Center(child: CircularProgressIndicator()),
);
}
return const ScanBody();
}}
I think context is not supposed to be use in provider but I am not sure what to do. Please help.