【问题标题】:Flutter/Firebase : How can i access the current user without using '.then(...)' functionFlutter/Firebase:如何在不使用 '.then(...)' 函数的情况下访问当前用户
【发布时间】:2018-11-16 13:41:03
【问题描述】:

我试图避免在我需要访问当前用户的 UID 的所有代码中使用 .then((u) { return u.uid }) 函数,而只需调用 getCurrentUser().uid 以获得更快的访问速度。但是,它给了我一个错误The getter 'uid' was called on null.,但它不是空的,因为它确实在控制台中打印,但只是在显示它为空并且由于某种原因最后出现错误之后。我对 Future/Async/Await 逻辑不太了解,因此我们将不胜感激!

class UsersAPI {
  final DatabaseReference usersRef = FirebaseDatabase.instance.reference().child(Config.users);

  Future<FirebaseUser> currentUser() async {
    return await FirebaseAuth.instance.currentUser();
  }

  FirebaseUser getCurrentUser() {
    FirebaseUser user;

    this.currentUser().then((u) {
      user = u;
      print('USER 1 $user'); // Prints after 'USER 2'
    });

    print('USER 2 $user'); // Prints first

    if (user != null) {
      return user;
    } else {
      return null;
    }
  }

  DatabaseReference getCurrentUserRef() {
    return this.usersRef.child(this.getCurrentUser().uid); // GIVES THE 'uid' WAS CALLED ON NULL ERROR
  }

  observeCurrentUser(Function onSuccess(User u)) {
    this.usersRef.child(this.getCurrentUser().uid).onValue.listen( (event) { // GIVES THE 'uid' WAS CALLED ON NULL ERROR
      DataSnapshot snapshot = event.snapshot;

      if (snapshot.value != null) {
        User user = User().transform(snapshot.key, snapshot.value);
        onSuccess(user);
      }
    });
  }

  observeUser(String userID, Function onSuccess(User u), Function onFailure(String e)) {
    this.usersRef.child(userID).onValue.listen( (e) {
      DataSnapshot snapshot = e.snapshot;
      if (snapshot.value != null) {
        User user = User().transform(snapshot.key, snapshot.value);
        onSuccess(user);
      } else {
        onFailure("User Not Found...");
      }
    });
  }
}

示例用法 - 工作:

APIs().usersAPI.currentUser().then((u) {
  APIs().usersAPI.observeUser(u.uid, (u) {
    onSuccess(u);
  }, (e) {
    print(e);
  });
});

不起作用:

APIs().usersAPI.observeCurrentUser((u) {
  onSuccess(u);
});

【问题讨论】:

  • 您需要返回一个Future&lt;FirebaseUser&gt; 并将其用作Future。所以你需要使用then()await
  • 当我只需要访问其中的内容时,要避免在所有代码中使用then()。我添加了有效的示例和无效的示例。不起作用的代码是我的目标。尽量减少代码行数。
  • 你不能让异步函数神奇地变为异步。如果你调用了一个异步方法并想等待它的结果,整个调用层次就变成了异步的。
  • 如果您想减少嵌套/代码行数,您可能需要查看await
  • 不,但是为什么我的 getCurrentUser() 函数不工作我在那里调用,但直到运行其余代码后才会调用它

标签: firebase dart firebase-authentication flutter


【解决方案1】:
  DatabaseReference getCurrentUserRef() async {
    return this.usersRef.child((await this.getCurrentUser()).uid); =
  }

比打电话

var ref = await getCurrentUserRef()

漂亮一点

  DatabaseReference getCurrentUserRef() async {
    var firebaseUser = await this.getCurrentUser();
    return this.usersRef.child(firebaseUser.uid); 
  }

编辑:澄清一些关于异步的问题

你现在如何调用这个函数来获取引用?

假设你想更新用户的数据,你可以这样做

Firestore.instance.runTransaction((transaction) async {
  var reference = await getCurrentUserRef();
  await transaction.set(reference, someData);
  });

或者您想从该引用中读取数据

readAndProcessData() async {
  var reference = await getCurrentUserRef();
  DocumentSnapshot user = await reference.get();
  print(user.data.toString);
}

【讨论】:

  • 在您的第二个示例中,uid 不等于 uid,而是 FirebaseUser
  • 如果不返回 Future&lt;Type&gt;,我将无法使用 async/await,因此如果不调用 .then(),我将无法真正使用它
  • 如果您仍然认为需要使用.then,您能解释一下在什么情况下以及为什么?
  • 就在你调用api的时候,需要用await来做才能得到你的结果
  • 如果不返回Future(或不标记函数async,实际上是相同的),您显然不能使用async/await。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2018-03-31
相关资源
最近更新 更多