Adil Khalil
Adil Khalil

Reputation: 49

_CastError thrown building Obx : Null check operator used on a null value

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:

Another exception was thrown: Null check operator used on a null value

and I get this ugly screen:

enter image description here

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

Upvotes: 1

Views: 4477

Answers (3)

Adil Khalil
Adil Khalil

Reputation: 49

I looked for more. the error came from the fact that I did not fill in this property for the GetBuilder

init: ControlViewModel(),

Doing it correct the problem even with the first version of the code.

Upvotes: 2

Adil Khalil
Adil Khalil

Reputation: 49

i finally found the solution. Using the flutter dev tools for debugging, i noticed that the GetBuilder returned by the Obx((){}) inline function wasn't instantiated each time the error occurred. So i created a GetBuilder variable in the top of the build() method, and i instantiated it. Then in the Obx((){}) inline function i modified my code to return the object i instantiated above.

here is the only modification i made in the code, other classes and functions didn't change:

class ControlView extends GetWidget<AuthViewModel>{

  @override
  Widget build(BuildContext context) {

    LoginView loginView = LoginView();
    //ControlViewModel ctrlvwmdl = ControlViewModel();
    GetBuilder<ControlViewModel> getbuilder = GetBuilder<ControlViewModel>(
      init: ControlViewModel(),
      builder: (controller) => Scaffold(
        body: controller.currentScreen,
        bottomNavigationBar: bottomNavigationBar(),
      ),
    );

    print(">> ControlView.build() : new call of the method.");
    return Obx(() {
      return (Get.find<AuthViewModel>().user == null)
          ? loginView
          : getbuilder;
    });
  }
}

Upvotes: 0

Abdallah Nassar
Abdallah Nassar

Reputation: 81

enter image description hereenter image description here

[Null check operator used on a null value] error means that a (!), Which was used to check if a certain value/parameter is null, received a null value before it, therefore it performed it's functionality and caused a big error.

I don't have all of your code, but I think that the problem could be caused by one of two lines in the included pictures.

If not, then at everyplace where you use the Null check operator(!) You should do the following:

  1. Print the value right above the line that contains the (!)
  2. Make sure that a null value never reaches a (!) Operator, or add a condition to check if the value is null, and overwrite it with a non-null value or do some logic or your own.

Bottom line, don't let any value reach a Null-check operator(!) While being null.

Upvotes: 0

Related Questions