**Every time I open a specific page on my App this error shows up: **
Exception has occurred. FlutterError (dependOnInheritedWidgetOfExactType<_ScaffoldMessengerScope>() or dependOnInheritedElement() was called before _AccountPageState.initState() completed. When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget. Typically references to inherited widgets should occur in widget build() methods. Alternatively, initialization based on inherited widgets can be placed in the didChangeDependencies method, which is called after initState and whenever the dependencies change thereafter.)
This is my Code on the Page where the error comes:
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:thrive/components/avatar.dart';
import 'package:thrive/main.dart';
import 'package:thrive/pages/creator_page.dart';
import 'package:thrive/pages/userlogin.dart';
class AccountPage extends StatefulWidget {
const AccountPage({super.key});
@override
State<AccountPage> createState() => _AccountPageState();
}
class _AccountPageState extends State<AccountPage> {
final _usernameController = TextEditingController();
final _websiteController = TextEditingController();
String? _imageUrl;
String? _avatarUrl;
var _loading = true;
/// Called once a user id is received within `onAuthenticated()`
Future<void> _getProfile() async {
setState(() {
_loading = true;
});
try {
final userId = supabase.auth.currentSession!.user.id;
final data =
await supabase.from('profiles').select().eq('id', userId).single();
_usernameController.text = (data['username'] ?? '') as String;
_websiteController.text = (data['website'] ?? '') as String;
_imageUrl = data['avatar_url'];
_avatarUrl = (data['avatar_url'] ?? '') as String;
} on PostgrestException catch (error) {
if (mounted) context.showSnackBar(error.message, isError: true);
} catch (error) {
if (mounted) {
context.showSnackBar('Unexpected error occurred', isError: true);
}
} finally {
if (mounted) {
setState(() {
_loading = false;
});
}
}
}
/// Called when user taps `Update` button
Future<void> _updateProfile() async {
setState(() {
_loading = true;
});
final userName = _usernameController.text.trim();
final website = _websiteController.text.trim();
final user = supabase.auth.currentUser;
final updates = {
'id': user!.id,
'username': userName,
'website': website,
'updated_at': DateTime.now().toIso8601String(),
};
try {
await supabase.from('profiles').upsert(updates);
if (mounted) context.showSnackBar('Successfully updated profile!');
} on PostgrestException catch (error) {
if (mounted) context.showSnackBar(error.message, isError: true);
} catch (error) {
if (mounted) {
context.showSnackBar('Unexpected error occurred', isError: true);
}
} finally {
if (mounted) {
setState(() {
_loading = false;
});
}
}
}
Future<void> _signOut() async {
try {
await supabase.auth.signOut();
} on AuthException catch (error) {
if (mounted) context.showSnackBar(error.message, isError: true);
} catch (error) {
if (mounted) {
context.showSnackBar('Unexpected error occurred', isError: true);
}
} finally {
if (mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const Userlogin()),
);
}
}
}
@override
void initState() {
super.initState();
_getProfile();
}
@override
void dispose() {
_usernameController.dispose();
_websiteController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile'), actions: <Widget>[
IconButton(
icon: const Icon(Icons.group_add_rounded),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => Creatorpage(),),);
},
),
],
),
body: ListView(
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
children: [
Avatar(imageUrl: _imageUrl, onUpload: (imageUrl) async {
setState(() {
_imageUrl = imageUrl;
});
final userId = supabase.auth.currentUser!.id;
await supabase.from('profiles').update({'avatar_url': imageUrl}).eq('id', userId);
}),
SizedBox(height: 12),
TextFormField(
controller: _usernameController,
decoration: InputDecoration(labelText: 'User Name', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12))),
),
const SizedBox(height: 18),
TextFormField(
controller: _websiteController,
decoration: InputDecoration(labelText: 'Headline', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12))),
),
const SizedBox(height: 18),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
onPressed: _loading ? null : _updateProfile,
child: Text(_loading ? 'Saving...' : 'Update', style: TextStyle(color: Theme.of(context).colorScheme.surface),),
),
const SizedBox(height: 18),
TextButton(onPressed: _signOut, child: Text('Sign Out', style: TextStyle(color: Theme.of(context).colorScheme.inversePrimary),)),
],
),
);
}
}
And here is my main.dart:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:thrive/components/dark_mode.dart';
import 'package:thrive/components/light_mode.dart';
import 'package:thrive/pages/account_page.dart';
import 'package:thrive/pages/homepage.dart';
Future<void> main() async {
await Supabase.initialize(
url: '_________________',
anonKey: '_____________',
);
runApp(const MyApp());
}
final supabase = Supabase.instance.client;
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _selectedIndex = 0;
// Navigation list for the navbar
static const List<Widget> _widgetOptions = <Widget>[
Homepage(),
Text("Communities"),
AccountPage(),
];
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarColor: Colors.transparent,
));
return MaterialApp(title: 'Supabase Flutter',
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
// NavBar
bottomNavigationBar: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15.0,
vertical: 20.0
),
child: GNav(
gap: 8,
padding: EdgeInsets.all(16),
activeColor: Theme.of(context).colorScheme.surface,
tabBackgroundColor: Theme.of(context).colorScheme.secondary,
tabs: [
// HomePage
GButton(
icon: Icons.home_rounded,
iconColor: Theme.of(context).colorScheme.secondary,
text: 'Home',
),
// CommunitiesPage
GButton(
icon: Icons.people_alt_rounded,
iconColor: Theme.of(context).colorScheme.secondary,
text: 'Communities',
),
// ProfilePage
GButton(
icon: Icons.person_rounded,
iconColor: Theme.of(context).colorScheme.secondary,
text: 'Profile',
),
],
selectedIndex: _selectedIndex,
onTabChange: (index){
setState(() {
_selectedIndex = index;
});
},
),
),
),
theme: lightMode,
darkTheme: darkMode,
);
}
}
extension ContextExtension on BuildContext {
void showSnackBar(String message, {bool isError = false}) {
ScaffoldMessenger.of(this).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: isError
? Theme.of(this).colorScheme.error
: Theme.of(this).snackBarTheme.backgroundColor,
),
);
}
}
The error comes since I added this Page:
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:thrive/components/avatar_display.dart';
import 'package:thrive/main.dart';
class Creatorpage extends StatefulWidget {
const Creatorpage({super.key});
@override
State<Creatorpage> createState() => _CreatorpageState();
}
class _CreatorpageState extends State<Creatorpage> {
final _usernameController = TextEditingController();
final _websiteController = TextEditingController();
String? _imageUrl;
String? _avatarUrl;
var _loading = true;
/// Called once a user id is received within `onAuthenticated()`
Future<void> _getProfile() async {
setState(() {
_loading = true;
});
try {
final userId = supabase.auth.currentSession!.user.id;
final data =
await supabase.from('profiles').select().eq('id', userId).single();
_imageUrl = data['avatar_url'];
_avatarUrl = (data['avatar_url'] ?? '') as String;
} on PostgrestException catch (error) {
if (mounted) context.showSnackBar(error.message, isError: true);
} catch (error) {
if (mounted) {
context.showSnackBar('Unexpected error occurred', isError: true);
}
} finally {
if (mounted) {
setState(() {
_loading = false;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
// AppBar
appBar: AppBar(
leading: IconButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => Creatorpage(),),);
},
icon: Icon(Icons.arrow_back_ios_new_rounded),
),
),
body: ListView(
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
children: [
AvatarDisplay(imageUrl: _imageUrl, onUpload: (imageUrl) async {
setState(() {
_imageUrl = imageUrl;
});
final userId = supabase.auth.currentUser!.id;
await supabase.from('profiles').update({'avatar_url': imageUrl}).eq('id', userId);
}),
]
)
);
}
}
Before I added this new Page a Account page comes up. And now the app crashes.
Can someone help me?
Because you're trying to access the ScaffoldMessenger
in the initState
method of your _AccountPageState
class. The initState
method is called before the widget is built, so the ScaffoldMessenger
is not available yet.
You can move the call to _getProfile
to the didChangeDependencies
method, which is called after the widget is built and the dependencies are established.