'App is logging out on restart using GetX state management. Sign in normally but when restated the app looses its state
I am very new to Dart, and coding in general. I have produced this code after watching tutorials on YouTube. For the most part, I have been able to troubleshoot most of my problems on my own, yet I cannot figure out my most recent errors. I made a simple app using GetX and firebase. The app logs in but when I do a restart app logs out. my objective is the user must stay on HomePage() until he is not logged out. On logout the app should go to LandingPage
Here is my auth controller:-
import 'package:definer_lms/views/views.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
class AuthController extends GetxController {
static AuthController instance = Get.find();
late Rx<User?> _user;
FirebaseAuth auth = FirebaseAuth.instance;
@override
void onReady() {
super.onReady();
_user = Rx<User?>(auth.currentUser);
_user.bindStream(auth.userChanges());
ever(_user, _initialScreen);
}
_initialScreen(User? user) {
if (user == null) {
print("loging Page");
Get.offAll(() => const LandingPage());
} else {
Get.offAll(() => const HomePage());
}
}
void signup(String email, password) async {
try {
await auth.createUserWithEmailAndPassword(
email: email, password: password);
} catch (e) {
Get.snackbar(
"About User",
"User Message",
backgroundColor: Colors.redAccent,
snackPosition: SnackPosition.BOTTOM,
titleText: const Text(
"Account creation failed",
style: TextStyle(color: Colors.white),
),
messageText: Text(
e.toString(),
style: const TextStyle(color: Colors.white),
),
);
}
}
void signIn(String email, password) async {
try {
await auth.signInWithEmailAndPassword(email: email, password: password);
} catch (e) {
Get.snackbar(
"About Login",
"Login Message",
backgroundColor: Colors.redAccent,
snackPosition: SnackPosition.BOTTOM,
titleText: const Text(
"Account login failed",
style: TextStyle(color: Colors.white),
),
messageText: Text(
e.toString(),
style: const TextStyle(color: Colors.white),
),
);
}
}
void logOut() async {
await auth.signOut();
}
}
Splash Screen
import 'dart:async';
import 'package:definer_lms/views/views.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
Timer(
Duration(seconds: 3),
() => {
Get.off(LandingPage(), transition: Transition.rightToLeftWithFade)
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xff2AA8A1),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 200,
width: 200,
child: Image.asset('images/dlw.png'),
),
const Padding(
padding: EdgeInsets.only(top: 100),
child: CircularProgressIndicator(
backgroundColor: Color(0xff2AA8A1),
color: Colors.white,
),
)
],
),
),
);
}
}
My Landing Page:-
import 'dart:async';
import 'package:flutter/material.dart';
import 'views.dart';
import 'package:get/get.dart';
class LandingPage extends StatefulWidget {
const LandingPage({Key? key}) : super(key: key);
@override
_LandingPageState createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: SizedBox(
height: 300,
width: 300,
child: Image.asset('images/definerLogo.gif'),
),
),
),
bottomNavigationBar: BottomAppBar(
color: Colors.blueAccent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
MaterialButton(
onPressed: (){
print('Bottom Button Pressed');
},
child: Text('Browse', style: TextStyle(color: Colors.grey.shade300, fontSize: 20.0),),
),
MaterialButton(
onPressed: (){
Get.to(SignIn());
},
child: Text('Sign In', style: TextStyle(color: Colors.grey.shade300, fontSize: 20.0),),
)
],
),
),
);
}
}
My Home Page
import 'package:definer_lms/controllers/authController.dart';
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(onPressed: ()=> AuthController.instance.logOut(), child: Text('Logout'))
],
),
),
);
}
}
Run Message While Login:
[GETX] GOING TO ROUTE /SignIn
I/FirebaseAuth( 6676): [FirebaseAuth:] Preparing to create service connection to
fallback implementation
W/System ( 6676): Ignoring header X-Firebase-Locale because its value was null.
W/System ( 6676): Ignoring header X-Firebase-Locale because its value was null.
D/FirebaseAuth( 6676): Notifying id token listeners about user (
lpbfNUpaEIQ9s38FtWmaGTfmFjo1 ).
[GETX] GOING TO ROUTE /HomePage
[GETX] REMOVING ROUTE /SignIn
[GETX] REMOVING ROUTE /LandingPage
Run message after restarting App
Performing hot restart...
Syncing files to device Android SDK built for x86...
Restarted application in 932ms.
W/DynamiteModule( 6676): Local module descriptor class for
com.google.android.gms.providerinstaller.dynamite not found.
I/DynamiteModule( 6676): Considering local module
com.google.android.gms.providerinstaller.dynamite:0 and remote module
com.google.android.gms.providerinstaller.dynamite:0
W/ProviderInstaller( 6676): Failed to load providerinstaller module: No acceptable module com.google.android.gms.providerinstaller.dynamite found. Local version is 0 and remote version is 0.
W/ProviderInstaller( 6676): Failed to report request stats:
com.google.android.gms.common.security.ProviderInstallerImpl.reportRequestStats [class
android.content.Context, long, long]
W/ConnectivityManager.CallbackHandler( 6676): callback not found for CALLBACK_AVAILABLE
message
[GETX] Instance "AuthController" has been created
[GETX] Instance "AuthController" has been initialized
[GETX] Instance "GetMaterialController" has been created
[GETX] Instance "GetMaterialController" has been initialized
[GETX] GOING TO ROUTE /HomePage
[GETX] REMOVING ROUTE /
W/libc ( 6676): calloc(434055556, 1) failed: returning null pointer
======== Exception caught by image resource service ================================================
The following _Exception was thrown resolving an image frame:
Exception: Codec failed to produce an image, possibly due to invalid image data.
When the exception was thrown, this was the stack:
Image provider: AssetImage(bundle: null, name: "images/dlw.png")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#55b5e(), name: "images/dlw.png", scale: 1.0)
=============================================================================
[GETX] WARNING, consider using: "Get.off(() => Page())" instead of "Get.off(Page())".
Using a widget function instead of a widget fully guarantees that the widget and its
controllers will be removed from memory when they are no longer used.
[GETX] REPLACE ROUTE /HomePage
[GETX] NEW ROUTE /LandingPage
Can anyone Help
Solution 1:[1]
You can try changing your AuthController extends from GetxController to GetxService.
And declare the AuthController on the main.dart:
await Firebase.initializeApp();
await Get.putAsync<AuthController>(
() async => AuthController());
GetxService unlike GetxController, does not automatically dispose when you dispose a page or when Get.delete() is used. Thats why it's commonly used for Auth control as an example.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
