Flutter GetX package Firebase Auth and FireStore "null check operator used on a null value"

Issue

First of all, I’m asking a question for the first time, I’m sorry if I’m asking incorrectly and incompletely, I will give you the information you want immediately.

Hey, I was following the tutorial in this video but I am getting an error like this.
video tutorial: https://www.youtube.com/watch?v=BiV0DcXgk58&t=314s&ab_channel=TadasPetra

Error is this:
Error simulator picture

I am getting this error, but the account is created in firebase Auth and the data I want is saved in FireStore database.

Flutter version: 2.2.3

pubspec.yaml

  cloud_firestore: ^0.13.5
  firebase_core: ^0.4.5
  firebase_storage: ^3.1.6
  get: ^4.3.8

Error debug console text

[GETX] Instance "AuthController" has been created
[GETX] Instance "AuthController" has been initialized
[GETX] Instance "GetMaterialController" has been created
[GETX] Instance "GetMaterialController" has been initialized

════════ Exception caught by widgets library ═══════════════════════════════════
The following _CastError was thrown building Root:
Null check operator used on a null value

The relevant error-causing widget was
Root
lib/main.dart:20
When the exception was thrown, this was the stack
#0      GetXState.initState
package:get/…/rx_flutter/rx_getx_widget.dart:78
#1      StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:4711
#2      ComponentElement.mount
package:flutter/…/widgets/framework.dart:4548
#3      Element.inflateWidget
package:flutter/…/widgets/framework.dart:3611
#4      Element.updateChild
package:flutter/…/widgets/framework.dart:3363

All files

Main.dart code

    void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      initialBinding: AuthBinding(),
      theme: ThemeData(scaffoldBackgroundColor: bgColor),
      home: Root(),
    );
  }
}

Root.dart code

class Root extends GetWidget<AuthController> {
  @override
  Widget build(BuildContext context) {
    return GetX(
      initState: (_) async {
        Get.put<UserController>(UserController());
      },
      builder: (_) {
        if (Get.find().user?.uid != null) {
          return SMBottomNavBar();
        } else {
          return SignInScreen();
        }
      },
    );
  }
}

userController.dart

class UserController extends GetxController {
  Rx<UserModel> _userModel = UserModel().obs;

  UserModel get user => _userModel.value;

  set user(UserModel value) => this._userModel.value = value;

  void clear() {
    _userModel.value = UserModel();
  }
}

authController.dart

class AuthController extends GetxController {
  FirebaseAuth _auth = FirebaseAuth.instance;
  Rxn<FirebaseUser> _firebaseUser = Rxn<FirebaseUser>();

  FirebaseUser get user => _firebaseUser.value;

  @override
  onInit() {
    _firebaseUser.bindStream(_auth.onAuthStateChanged);
  }

  void createUserAccount(String userName, String email, String password) async {
    try {
      AuthResult _authResult = await _auth.createUserWithEmailAndPassword(
          email: email.trim(), password: password);
      //create user in database.dart
      UserModel _user = UserModel(
         userID: _authResult.user.uid, userName: userName, userEmail: email
      );
      if (await DatabaseServices().createNewUser(_user)) {
        Get.find<UserController>().user = _user;
        Get.back();
      }
    } catch (e) {
      Get.snackbar(
        "Error creating Account",
        e.message,
      );
    }
  }

  void logInUser(String email, String password) async {
    try {
      AuthResult _authResult = await _auth.signInWithEmailAndPassword(
          email: email.trim(), password: password);
      Get.find<UserController>().user =
          await DatabaseServices().getUser(_authResult.user.uid);
    } catch (e) {
      Get.snackbar(
        "Error signing in",
        e.message,
        
      );
    }
  }

  void logOutUser() async {
    try {
      await _auth.signOut();
      Get.find<UserController>().clear();
    } catch (e) {
      Get.snackbar(
        "Error signing out",
        e.message,
        
      );
    }
  }
}

authBinding.dart

class AuthBinding extends Bindings {
  @override
  void dependencies() {
    Get.put<AuthController>(AuthController(), permanent: true);
  }
}

user.dart(Model)

class UserModel {
  String userID;
  String userEmail;
  String userName;
  String userDisplayName;
  String userProfilePhotoURL;
  String userBioText;
  int userScore;

  UserModel(
      {this.userID,
      this.userEmail,
      this.userName,
      this.userDisplayName,
      this.userProfilePhotoURL,
      this.userBioText,
      this.userScore});

  UserModel.fromDocumentSnapshot(DocumentSnapshot doc) {
    userID = doc.documentID;
    userEmail = doc['userEmail'];
    userName = doc['userName'];
    userDisplayName = doc['userDisplayName'];
    userProfilePhotoURL = doc['userProfilePhotoURL'];
    userBioText = doc['userBioText'];
    userScore = doc['userScore'];
  }
}

Solution

You need to insert the type into your GetX widget.

return GetX<AuthController>( // add AuthController here
      initState: (_) async {
        Get.put<UserController>(UserController());
      },
...

Your other issue is here

if (Get.find().user?.uid != null) {
          return SMBottomNavBar();
        } 

If you use Get.find, same thing, always provide the type.

Get.find<AuthController>().user?.uid

But since you’re using GetWidget<AuthController> you can do this

if (controller.user?.uid != null) {
          return SMBottomNavBar();
        }
...

Answered By – Loren.A

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.