I have problem in my project.
I use Flutter and GetX to create routes.
For now it's a simple project but I have error when I refresh this code in my VS.
I check my project on Chrome browser and I have this info in my debugger:
This app is linked to the debug service: ws://127.0.0.1:49847/Kvc6Hh7Hagk=/ws
Debug service listening on ws://127.0.0.1:49847/Kvc6Hh7Hagk=/ws
Connecting to VM Service at ws://127.0.0.1:49847/Kvc6Hh7Hagk=/ws
***** Supabase init completed Instance of 'Supabase'
***** SupabaseDeepLinkingMixin startAuthObserver
**** onAuthStateChange: AuthChangeEvent.initialSession
[GETX] Instance "GetMaterialController" has been created
[GETX] Instance "GetMaterialController" has been initialized
[GETX] GOING TO ROUTE /splashpage
[GETX] GOING TO ROUTE /LoginScreen
[GETX] REMOVING ROUTE /splashpage
My project work like this - first user go to splashScreen - if he logged then he goes to HomePage() when not he will be redirect to /LoginScreen().
For now I dont know why /spashpage Is twice but there is no problem with project.
No errors - everything is ok.
Then when I upload some new elements of code (for example I add simple change) and I save this project then I have hot reload in my VS and I have errors :
1)
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following TypeErrorImpl was thrown building _FocusInheritedScope:
Unexpected null value.
The relevant error-causing widget was:
Directionality
Directionality:file://.pub-cache/hosted/pub.dev/get-4.6.6/lib/get_navigation/src/root/get_material_app.dart:328:12
and second error in my main.dart file?
Another exception was thrown: A GlobalKey was used multiple times inside one widget's child list.
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building _FocusInheritedScope:
A GlobalKey was used multiple times inside one widget's child list.
The offending GlobalKey was: [LabeledGlobalKey<NavigatorState>#c60d4 Key Created by default]
The parent of the widgets with that key was:
_FocusInheritedScope
The first child to get instantiated with that key became:
Navigator-[LabeledGlobalKey<NavigatorState>#c60d4 Key Created by default]
The second child that was to be instantiated with that key was:
_FocusInheritedScope
A GlobalKey can only be specified on one widget at a time in the widget tree.
Maybe code will help
main.dart
import 'package:get/get.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: 'url key',
anonKey:
'my anon key',
debug: true,
);
runApp(MyApp());
}
final supabase = Supabase.instance.client;
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: '/splashpage',
getPages: [
GetPage(name: '/splashpage', page: () => SplashPage()),
GetPage(name: '/loginpage', page: () => LoginScreen()),
GetPage(name: '/homepage', page: () => HomePage()),
],
title: 'Flutter Admin Panel2',
theme: lightMode,
darkTheme: darkMode,
);
}
}
login_page.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class LoginScreen extends StatelessWidget {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
double displayHeight(BuildContext context) {
return displaySize(context).height;
}
double displayWidth(BuildContext context) {
return displaySize(context).width;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
Container(
padding: EdgeInsets.all(24),
width: 400,
height: double.maxFinite,
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.blue.shade300,
width: 1,
),
),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset('assets/images/$logo', width: 200, height: 200),
SizedBox(height: 50),
TextField(
key: Key('email-field'),
controller: _emailController,
decoration: textFieldDecoration.copyWith(labelText: 'Email'),
),
SizedBox(height: 20),
TextField(
key: Key('password-field'),
controller: _passwordController,
obscureText: true,
decoration:
textFieldDecoration.copyWith(labelText: 'Password'),
),
SizedBox(height: 20),
Container(
width: 200,
height: 50,
child: ElevatedButton(
style: buttonStyle1,
onPressed: () async {
try {
final email = _emailController.text.trim();
final password = _passwordController.text.trim();
if (email.isEmpty || password.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Email and password cannot be empty.'),
backgroundColor: Colors.red,
),
);
return;
}
final response = await supabase.auth.signInWithPassword(
email: email, password: password);
if (response.user != null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Login Success'),
backgroundColor: Colors.green,
),
);
Get.to(() => HomePage());
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Login failed, please try again.1'),
backgroundColor: Colors.red,
),
);
}
} catch (error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text('An error occurred: ${error.toString()}'),
backgroundColor: Colors.red,
),
);
}
},
child: Text('Login'),
),
),
],
),
),
Container(
width: displayWidth(context) - 400,
height: double.maxFinite,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/background_image.jpg'),
fit: BoxFit.cover,
),
),
),
],
),
);
}
}
and splash_page.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
class SplashPage extends StatefulWidget {
const SplashPage({super.key});
@override
State<SplashPage> createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_redirect();
});
}
Future<void> _redirect() async {
// Zasymulowany opóźniony czas ładowania, aby zobaczyć CircularProgressIndicator
await Future.delayed(const Duration(seconds: 2));
final session = Supabase.instance.client.auth.currentSession;
if (!mounted) return;
if (session != null) {
Get.offAll(() => HomePage());
} else {
Get.offAll(() => LoginScreen());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
SizedBox(height: 20),
Text('Loading...'),
],
),
),
);
}
}
so as you can see code is not big but there is a problem in the beginning.
Important: When I stop project and run this project again problem not occur.
But when I do some small change in code and hot reload my project then the problem occur (exceptions).
Do you have some idea what is wrong ?
Thank you for your time and help
Solution to this is you need to define "unknownRoute" inside your GetMaterialApp like this :
unknownRoute: GetPage(
name: "/splash",
page: () => SplashView(),
binding: SplashBinding(),
),
you can define your own views and route name. Hope it helps, Happy Coding!