dart - How can I resolve 'The argument type 'Null' can't be assigned to the parameter type 'MyUser'.'

Viewed 3310

I am trying to implement a simple signup page. The following is my main.dart code:

main.dart

void main() async {
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<MyUser>.value(
        value: AuthService().user,
        initialData: null,
        child: MaterialApp(
          home: Wrapper(),
          debugShowCheckedModeBanner: false,
        )
    );
  }
}

I am seeing this error on the initialData: null, line:

The argument type 'Null' can't be assigned to the parameter type 'MyUser'.

This is my MyUser class:

user.dart

class MyUser {
  final String uid;
  MyUser({this.uid});
}

It is showing me the following error on uid in line 3:

The parameter 'uid' can't have a value of 'null' because of its type, but the implicit default value is 'null'.
Try adding either an explicit non-'null' default value or the 'required' modifier.

I am fairly new to flutter development so I'm not sure what this means and how to resolve it. I wasn't able to find any relevant help online. Any help will be appreciated.

EDIT 1:

The entire auth.dart file:

class AuthService {

  final FirebaseAuth _auth = FirebaseAuth.instance;

  // create user obj based on firebase user
  MyUser? _userFromFirebaseUser(User user) {
    // ignore: unnecessary_null_comparison
    return user != null ? MyUser(uid: user.uid) : null;
  }

  // auth change user stream
  Stream<MyUser> get user {
    return _auth.authStateChanges()
    //.map((FirebaseUser user) => _userFromFirebaseUser(user));
    .map(_userFromFirebaseUser);
  }


  // sign in with email and password
  Future signInWithEmailAndPassword(String email, String password) async {
    try {
      UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
      User? user = result.user;
      return _userFromFirebaseUser(user!);
    } catch (error) {
      print(error.toString());
      return null;
    }
  }

  // register with email and password
  Future registerWithEmailAndPassword(String email, String password) async {
    try {
      UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
      User? user = result.user;
      return _userFromFirebaseUser(user!);
    } catch (error) {
      print(error.toString()+"oollala");
      return null;
    }
  }

  // sign out
  Future signOut() async {
    try {
      return await _auth.signOut();
    } catch (error) {
      print(error.toString());
      return null;
    }
  }
}

Error in:

Stream<MyUser> get user {
  return _auth.authStateChanges()
  .map(_userFromFirebaseUser);
}

It is showing me an error in _userFromFirebaseUser

The argument type 'MyUser? Function(User)' can't be assigned to the parameter type 'MyUser Function(User?)'.

2 Answers

You defined your property uid as a non-nullable String but it is declared as an optional value in your constructor because of the {} which means that it would have the default value null if not assigned.

To fix this error you either need to make uid non optional in your constructor:

MyUser(this.uid);

Or to make it a required parameter:

MyUser({required this.uid});

If it is intended that your uid can be null then you need to declare your variable like this:

final String? uid; // this is a nullable String variable

make sure you have provider 5.0.0 and then change your main.dart to

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return StreamProvider<MyUser?>.value(
      initialData: null,
      value: AuthService().user,
      child: MaterialApp(
        home: Wrapper(
      ),
    ),
    );
  }
}

Related