【问题标题】:Flutter - async function returns nullFlutter - 异步函数返回null
【发布时间】:2019-07-31 16:10:32
【问题描述】:

我已经断断续续地研究了几天,即使在搜索和挖掘之后,也没有弄清楚。

下面是两段相关的代码:

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 中正确创建用户,以及 Firebase 实时数据库中的 userProfile 条目。但是,无论出于何种原因,我永远无法在 register() 函数中获取实际的 FirebaseUser 对象。它总是返回如下错误:

    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

【问题讨论】:

    标签: firebase firebase-realtime-database dart flutter


    【解决方案1】:

    awaitthen 结合使用通常会造成混淆。重构您的 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;
    }
    

    【讨论】:

      【解决方案2】:

      问题在于链接 .then 有点“覆盖”前一个承诺的返回类型。

      这个函数自己返回一个Future&lt;FirebaseUser&gt;

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

      或遵循 Richard 的回答,它完全摆脱了 .then 并仅使用 await,这使您的代码看起来更清晰,更易于阅读,尤其是在存在异步链接时。

      【讨论】:

      • 感谢您的回复,Richard 的解决方案为我解决了这个问题,但这很好地解释了为什么它不起作用!
      猜你喜欢
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2014-10-29
      • 2021-01-11
      相关资源
      最近更新 更多