【问题标题】:Flutter and Firebase: How can i receive data from function?Flutter 和 Firebase:我如何从函数接收数据?
【发布时间】:2018-08-10 14:01:00
【问题描述】:

我使用以下函数从 Firestore 获取 userData:

Future<String>getRegisterUserData({String userID}) async {
Firestore.instance.collection("Users").document(userID).get().then(
  (datasnapshot) {
    if (datasnapshot.exists) {
      return datasnapshot.data['Email'];
    } else {
      return "Loading...";
    }
  },
);
}

我像这样在我的 UserProfilePage 上执行这个函数:

_email = widget.firestore.getRegisterUserData(widget.userID).toString();

但我总是得到打印语句:'Future' 的实例而不是保存的电子邮件地址......

我也试试这个:

Future<String> getRegisterUserData({String userID}) async {
String email;
Firestore.instance.collection("Users").document(userID).get().then(
  (datasnapshot) {
    if (datasnapshot.exists) {
      email = datasnapshot.data['Email'];
    } else {
      email = "Loading...";
    }
  },
);
return email;
}

打印语句总是一样的......

那么我的错误在哪里?我想在变量中的 UserProfilePage 上显示“电子邮件”的值,还是我的 firestore 函数不正确?

感谢您的帮助

【问题讨论】:

    标签: dart google-cloud-firestore flutter


    【解决方案1】:

    添加await 关键字。但在不同的地方。

    tempEmail = await widget.firestore.getRegisterUserData(widget.userID);
    setState(() {
      _email = tempEmail;
    });
    // we don't need toString as getRegisterUserData itself is returning Future<String>
    

    注意使用 await:当我们使用 await 时,包含它的方法/函数应该在其签名中包含 async

    或者你可以使用then

    widget.firestore.getRegisterUserData(widget.userID).then((email) {
       setState(() {
          _email = email;
       });
    });
    

    解释: widget.firestore.getRegisterUserData(widget.userID)Future&lt;String&gt; 类型。这就是为什么它被打印为'Future'的实例。我们必须通过awaitthen 块将Future 转换为字符串

    使用 SharedPreferences:

    Future<String> getEmail() async {
      final prefs = await SharedPreferences.getInstance();
      String email = prefs.getString('email');
      if (email != null) {
        return email;
      } else {
        email = await widget.firestore.getRegisterUserData(widget.userID);
        prefs.setString('email', email); //update shared preferences
        return email;
      }
    }
    
    // usage (may be in initState)
     widget.getEmail().then((email) {
       setState(() {
         _email = email;
       })
     })
    

    【讨论】:

    • 这不起作用。电子邮件地址不会在 TextFormField 中显示为 initialValue。初始值暂时不会显示...
    • 我们必须在获得数据后使用setState(() {}) 重新渲染。相应地更新了答案。
    • 感谢您的回答...我有最后一个问题:每次重新启动应用程序或重新呈现页面时,如何在不从 Firestore 查询的情况下保存电子邮件地址?我可以使用 initState-Method 来执行此操作吗?它如何与 YouTube 等应用配合使用?该应用还必须临时缓存数据
    • 您可以使用Shared_Preference,它最适合快速存储/获取小数据。参考pub.dartlang.org/packages/shared_preferences...
    • 如果我上面的回答有用,你可以投票/接受吗?
    【解决方案2】:

    更新

    根据您的信息,您需要FutureBuilder 才能等待响应来构建您的小部件:

      return FutureBuilder(
        future: getRegisterUserData(userID: "1234"),
        builder: (context, asyncsnapshot){
          return asyncsnapshot.hasData && asyncsnapshot.data != null ? TextFormField(
            initialValue: asyncsnapshot.data,
          ) : CircularProgressIndicator();
          }
      );
    

    【讨论】:

    • 我添加了 await 关键字,但问题仍然存在...我还能做些什么来解决问题?
    • 您确定您的收藏和数据存在吗?你能只返回一个测试字符串来确保
    • 是的,请看起来像这样:https://drive.google.com/file/d/1HMrLfXQ_rNWTJeAjpms2YXOao5WRT0Xs/view?usp=sharing 添加 catchError 方法后,我没有从 firestore 收到任何错误...
    • 你能打印一些东西吗:if (datasnapshot.exists) { after that ?
    • 是的,这行得通...但在我的应用程序中,我总是看到字符串:'Future' 的实例这是什么意思?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    相关资源
    最近更新 更多