Search code examples
flutterfirebasedartflutter-dependenciesflutter-getx

flutter - how to pass required parameters when they have not yet been initialized


I am creating a userModel instance inside my authController and want to add obs from Getx to that userModel like: Rx<model.User>? userModel = model.User().obs;, but the fields inside my model.User are all required.

How can I pass these parameters if they have not yet been initialized as they will get initialized after the user signs in?

I referred this github: Github where he has done it because his parameters are not "required" as it is old, but now flutter is null safe and is forcing "required" parameters in my user model.

required error

AuthController code:


class AuthController extends GetxController {
  static AuthController instance = Get.find();
  late Rx<User?> _user;
  // Rx<model.User>? userModel;
  Rx<model.User>? userModel = model.User().obs; //ERROR CAUSING LINE**

  @override
  void onReady() {
    super.onReady();
    _user = Rx<User?>(firebaseAuth.currentUser);
    _user.bindStream(firebaseAuth.authStateChanges());
    ever(_user, _setInitialScreen);
  }

  _setInitialScreen(User? user) {
    if (user == null) {
      Get.offAll(() => LoginScreen());
    } else {
      // userModel?.bindStream(listenToUser());
      Get.offAll(() => const HomeScreen());
      userModel?.bindStream(listenToUser());
      print(userModel);
    }
  }

  // registering the user
  void registerUser(String username, String email, String password) async {
    try {
      if (username.isNotEmpty && email.isNotEmpty && password.isNotEmpty) {
        // save our user to our auth and firebase firestore
        UserCredential cred = await firebaseAuth.createUserWithEmailAndPassword(
          email: email,
          password: password,
        );
        model.User user = model.User(
            name: username, email: email, uid: cred.user!.uid, cart: []);
        await firestore
            .collection('users')
            .doc(cred.user!.uid)
            .set(user.toJson());
      } else {
        Get.snackbar(
          'Error Creating Account',
          'Please enter all the fields',
        );
      }
    } catch (e) {
      Get.snackbar(
        'Error Creating Account',
        e.toString(),
      );
    }
  }

  void loginUser(String email, String password) async {
    try {
      if (email.isNotEmpty && password.isNotEmpty) {
        await firebaseAuth.signInWithEmailAndPassword(
            email: email, password: password);
        print('log success');
      } else {
        Get.snackbar(
          'Error Logging in',
          'Please enter all the fields',
        );
      }
    } catch (e) {
      Get.snackbar(
        'Error Logging in',
        e.toString(),
      );
    }
  }

  updateUserData(Map<String, dynamic> data) {
    print("UPDATED");
    firestore.collection('users').doc(_user.value?.uid).update(data);
  }

  Stream<model.User> listenToUser() => firestore
      .collection('users')
      .doc(_user.value?.uid)
      .snapshots()
      .map((snapshot) => model.User.fromSnap(snapshot));
}

User model code:


class User {
  // static const UID = "uid";
  // static const NAME = "name";
  // static const EMAIL = "email";

  String uid;
  String name;
  String email;
  List<CartItemModel> cart;

  User(
      {required this.name,
      required this.email,
      required this.uid,
      required this.cart});

  Map<String, dynamic> toJson() =>
      {"name": name, "email": email, "uid": uid, "cart": cart};

  // static User fromSnap(DocumentSnapshot snap) {
  static User fromSnap(DocumentSnapshot snap) {
    var snapshot = snap.data() as Map<String, dynamic>;
    return User(
        name: snapshot['name'],
        email: snapshot['email'],
        uid: snapshot['uid'],
        cart: _convertCartItems(snapshot['cart'] ?? []));
  }

  // List<CartItemModel> _convertCartItems(List cartFromDb) {
  static List<CartItemModel> _convertCartItems(List cartFromDb) {
    List<CartItemModel> _result = [];
    // logger.i(cartFromDb.lengt);
    print(cartFromDb.length);
    cartFromDb.forEach((element) {
      _result.add(CartItemModel.fromMap(element));
    });
    return _result;
  }
}

Solution

  • Add ? operator to tell explicity that the object can be null.

    So the code goes like:

    class User {
    
      String? uid;
      String? name;
      String? email;
      List<CartItemModel>? cart;
    
    }