0

I've been working on this off and on for a couple of days now, and even after searching, and digging, haven't figured it out.

Here are the two relevant pieces of code:

Future<FirebaseUser> signUp(String email, String password, String username) async {
FirebaseUser user = await _firebaseAuth.createUserWithEmailAndPassword(
    email: email, password: password).then((newUser) {
      var obj = {
        "active": true,
        "public": true,
        "email": email,
        "username":username
      };
      _profileRef.child(newUser.uid).set(obj).then((_) {
        print("inside");
        //print("new userId: ${newUser}");
        //return newUser;
      });
});
//print("outside");
return user;
}

And:

Future<void> register() async {
final formState = _formKey.currentState;

if(formState.validate()) {
  formState.save();

  try {
    //print("email: " + _email + ", pwd: " + _password);
    //FirebaseUser user = await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email,password: _password);
    //String uid = await widget.auth.signIn(_email, _password);
    FirebaseUser user = await widget.auth.signUp(_email, _password, _username);

    print("uid: " + user.uid);
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => HomePage(auth: widget.auth, userId: user.uid, onSignedOut: widget.onSignedIn,)));
    //Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => HomePage(auth: widget.auth, userId: uid, onSignedOut: widget.onSignedIn,)));
  } catch(e) {
    print(e);
  }
}
}

The signUp() function works properly, and correctly creates the user in Firebase, along with the userProfile entry in the Firebase realtime database. However, for whatever reason, I'm never able to get the actual FirebaseUser object back in the register() function. It always returns an error like the below:

    Connected Path: satisfied (Path is satisfied), interface: en0
Duration: 1.315s, DNS @0.001s took 0.004s, TCP @0.007s took 0.053s, TLS took 0.158s
bytes in/out: 5745/975, packets in/out: 9/9, rtt: 0.051s, retransmitted packets: 0, out-of-order packets: 0
[C3.1 8282B933-6D0B-4103-937C-173268FD0304 192.168.1.7:54700<->172.217.14.106:443]
Connected Path: satisfied (Path is satisfied), interface: en0
Duration: 0.441s, DNS @0.000s took 0.003s, TCP @0.005s took 0.054s, TLS took 0.152s
bytes in/out: 5040/1812, packets in/out: 9/9, rtt: 0.052s, retransmitted packets: 0, out-of-order packets: 0
flutter: NoSuchMethodError: The getter 'uid' was called on null.
Receiver: null
Tried calling: uid
flutter: inside

2 Answers 2

4

It's generally confusing to combine the use of await with then. Refactor your signUp method to remove the then.

Future<FirebaseUser> signUp(String email, String password, String username) async {
  FirebaseUser user = await _firebaseAuth.createUserWithEmailAndPassword(
    email: email, password: password);
  var obj = {
        "active": true,
        "public": true,
        "email": email,
        "username": username,
      };
  await _profileRef.child(user.uid).set(obj);
  return user;
}
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is that chaining .then kind of "overrides" the previous promise's return type.

This function returns a Future<FirebaseUser> by itself:

_firebaseAuth.createUserWithEmailAndPassword(...);

However you have a .then chain that returns nothing which is why no value is assigned to the final result of the Future and it remains null:

.then((newUser) {
  var obj = {
    "active": true,
    "public": true,
    "email": email,
    "username":username
  };
  _profileRef.child(newUser.uid).set(obj).then((_) {
    print("inside");
  };
  // Need to return newUser here.
};

You can either add a return newUser;:

_profileRef.child(newUser.uid).set(obj).then((_) {
    print("inside");
};
return newUser;

or follow Richard's answer which gets rid of .then altogether and use await only instead which make your code look cleaner and easier to read especially when there is async chaining.

1 Comment

Thank you for the response, Richard's solution solved the issue for me, but this is a great explanation of why it wasn't working!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.