i am new in flutter/dart and i'm trying to build an app with an observer to redirect user for sign in if it wasn't done
Here is my code
class ControlView extends GetWidget<AuthViewModel>{
@override
Widget build(BuildContext context) {
ControlViewModel ctrlvwmdl = ControlViewModel();
return Obx(() {
return (Get.find<AuthViewModel>().user == null)
? LoginView()
: GetBuilder<ControlViewModel>(
builder: (controller) => Scaffold(
body: controller.currentScreen,
bottomNavigationBar: bottomNavigationBar(),
),
);
});
}
Widget bottomNavigationBar() {
return GetBuilder<ControlViewModel>(
init: ControlViewModel(),
builder: (controller) => BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.search), label: 'search'.tr),
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined), label: 'reserve'.tr),
BottomNavigationBarItem(
icon: Icon(Icons.add), label: 'Déposer'),
BottomNavigationBarItem(
icon: Icon(Icons.email_outlined), label: 'Messages'),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline), label: 'Profil'),
],
currentIndex: controller.navigatorValue,
onTap: (index) {
controller.changeSelectedValue(index);
},
//elevation: 0,
//selectedItemColor: Colors.black,
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.yellow,
iconSize: 20,
),
);
}
}
My AuthViewModel class is below
class AuthViewModel extends GetxController {
FirebaseAuth _auth = FirebaseAuth.instance;
String? email, password, name;
Rxn<User> _firebaseUser = Rxn<User>();
String? get user => _firebaseUser.value?.email;
@override
void onInit() {
// TODO: implement onInit
super.onInit();
_firebaseUser.bindStream(_auth.authStateChanges());
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
}
void googleSignInMethod() async {
print(">> Google Sign In");
GoogleSignIn googleSignIn = GoogleSignIn(scopes: ['email']);
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
print(">> google user : $googleUser");
GoogleSignInAuthentication googleSignInAuthentication =
await googleUser!.authentication;
final AuthCredential googleCredential = GoogleAuthProvider.credential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken,
);
await _auth.signInWithCredential(googleCredential).then((user) {
print(">> app user : $user");
});
}
void facebookSignInMethod() async {
print(">> Facebook Sign In");
FacebookLogin facebookSignIn = new FacebookLogin();
final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
print(">> facebook result : $result");
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final FacebookAccessToken accessToken = result.accessToken;
final facebookAuthCredential =
FacebookAuthProvider.credential(accessToken.token);
await _auth.signInWithCredential(facebookAuthCredential).then((user){
print(">> app user : $user");
});
break;
case FacebookLoginStatus.cancelledByUser:
print(">> User cancelled login with FaceBook account");
break;
case FacebookLoginStatus.error:
print(">> Error when login with FaceBook account");
break;
}
}
void signInWithEmailAndPassword() async {
try {
print(">> email $email");
print(">> password $password");
await _auth
.signInWithEmailAndPassword(email: email!, password: password!)
.then((value) {
print(">> value $value");
});
} catch (err) {
print(err.toString());
Get.snackbar(
'Error login account',
err.toString(),
colorText: Colors.black,
snackPosition: SnackPosition.BOTTOM,
);
}
}
}
And here is my main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter App',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: AppBarTheme(
color: Colors.orange
),
),
initialBinding: Binding(),
home: Scaffold(
appBar: AppBar(
title: Text('Training App'),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {
debugPrint('Settings button tapped');
},
),
IconButton(
icon: Icon(
Icons.more_horiz,
color: Colors.white,
),
onPressed: () {
debugPrint('Menu button tapped');
},
)
],
),
drawer: SideBar(),
body: ControlView(),
),
translations: Translate(),
locale: Locale('fr'), //Default language
fallbackLocale: Locale('fr'), //Default language in case of error
);
}
}
I'm getting the strange behavior below:
- when i run the application for the first time, all is ok and i can login either with google sign in method, and the facebook sign in method and also with password and email sign in method
- when i ask the app to logout it does and all is ok
- since then, whenever i try to sign in again, it seem (after troubleshooting of course) that the app logs the user in successfully but when building the UI the exception below is thrown
Another exception was thrown: Null check operator used on a null value
and I get this ugly screen:
without signin out, i performed a hot reload and i got the same error with a new hint in addition, it says
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY╞═══════════════════════════════════════════
The following _CastError was thrown building Obx(has builder, state: _ObxState#37426): Null check operator used on a null value
The relevant error-causing widget was: Obx Obx:file:///C:/Users/yoozer/StudioProjects/swim_test/lib/view/control_view.dart:14:12
Here is the stack when the exception was thrown
The relevant error-causing widget was: Obx Obx:file:///C:/Users/yoozer/StudioProjects/swim_test/lib/view/control_view.dart:14:12
When the exception was thrown, this was the stack: #0 GetBuilderState.initState (package:get/get_state_manager/src/simple/get_state.dart:134:40) #1 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4805:57) #2 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4638:5) #3 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14) #4 Element.updateChild (package:flutter/src/widgets/framework.dart:3422:20) #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4690:16) #6 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4840:11) #7 Element.rebuild (package:flutter/src/widgets/framework.dart:4355:5) #8 StatefulElement.update (package:flutter/src/widgets/framework.dart:4872:5) #9 Element.updateChild (package:flutter/src/widgets/framework.dart:3412:15) #10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4690:16) #11 GetWidgetCacheElement.performRebuild (package:get/get_state_manager/src/simple/get_widget_cache.dart:35:11) #12 Element.rebuild (package:flutter/src/widgets/framework.dart:4355:5) #13 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2620:33) #14 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21) #15 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5) #16 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15) #17 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9) #18 SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:863:7) (elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch)
I spent long days troubleshooting the error and trying to understand what happen, I looked on the internet for a solution, a similar problem or a way to deeply inspect this behavior but i'm still stuck.
Any help will be welcome I will be very grateful

