Flutter - асинхронная функция возвращает ноль - PullRequest
0 голосов
/ 10 марта 2019

Я работаю над этим время от времени уже несколько дней, и даже после поиска и раскопок не понял.

Вот два соответствующих фрагмента кода:

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;
}

И:

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);
  }
}
}

Функция signUp () работает правильно и правильно создает пользователя в Firebaseвместе с записью userProfile в базе данных реального времени Firebase.Однако по какой-то причине я никогда не смог вернуть реальный объект FirebaseUser обратно в функцию register ().Всегда возвращается ошибка, подобная приведенной ниже:

    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 ]

2 голосов
/ 10 марта 2019

Обычно смешивает использование await с then. Рефакторинг вашего signUp метода для удаления 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;
}
1 голос
/ 10 марта 2019

Проблема в том, что цепочка .then "переопределяет" тип возврата предыдущего обещания.

Эта функция сама возвращает Future<FirebaseUser>:

_firebaseAuth.createUserWithEmailAndPassword(...);

Однако у вас есть.then цепочка, которая ничего не возвращает, поэтому конечному результату Future не присваивается никакого значения, и она остается 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.
};

Вы можете добавить return newUser;:

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

или следуйте ответу Ричарда, который полностью избавляется от .then и использует вместо него только await, что делает ваш код более чистым и легким для чтения, особенно при асинхронной цепочке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...