首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >及时从Firestore检索数据(在小部件构建(BuildContext上下文)之外)

问及时从Firestore检索数据(在小部件构建(BuildContext上下文)之外)
EN

Stack Overflow用户
提问于 2020-11-12 12:42:03
回答 1查看 124关注 0票数 0

如果你想了解一些背景知识,我问了一个类似的问题here。在我的flutter应用程序中,您可以发送电子邮件

代码语言:javascript
复制
  static getEmailCredentials(String email1, String password1) {
    email = email1;
    passw = password1;
  }

  sendMail() async {
    String username = email;//gets email from db 
    String password = passw;//gets password for email from db

    final SmtpServer = gmail(username, password); //fix one day

    final message = Message()
      ..from = Address(username)
      ..recipients.add("xxx@gmail.com")
      ..subject = "From "+name //need name here from db
      ..html = "<h3>" + emailContent.text + "</h3>";

    try {
      final SendReport = await send(message, SmtpServer);
      Fluttertoast.showToast(
        msg: "Message sent! Hang in there!",
        gravity: ToastGravity.CENTER,
      );
    } on MailerException catch (e) {
      e.toString();
      Fluttertoast.showToast(
        msg: "Message failed to send! Try again?",
        gravity: ToastGravity.CENTER,
      );
    }
  }
}

如上所示。我知道这可能不是最好的存储电子邮件和密码,但它的工作(很好,它会工作,如果数据及时到达)。所以我的问题是,我会在应用程序的开始运行这个函数,但有时它不会及时加载。

UI代码:

代码语言:javascript
复制
class EmergencyReport extends StatelessWidget {
  EmergencyReport();

  static String email;
  static String passw;
  final TextEditingController emailContent = TextEditingController();

  @override
  Widget build(BuildContext context) {
    getEmailCredentialsF();//function that calls to db
    DateTime now = DateTime.now();
    DateTime weekAgo = now.subtract(new Duration(days: 7));
    DateFormat formadate = DateFormat('dd-MM');
    String formatedDate = formadate.format(now); // current date formatted
    String weekAgoForm =
        formadate.format(weekAgo); // date from week ago formatted
    countDocuments();
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.blueGrey,
        body: SingleChildScrollView(
          child: Center(
            child: Column(
              children: <Widget>[
                Align(
                  alignment: Alignment.topLeft,
                  child: Container(
                    width: 54,
                    margin: EdgeInsets.only(top: 44),
                    child: FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Column(
                        children: <Widget>[Icon(Icons.arrow_back_ios)],
                      ),
                    ),
                  ),
                ),
                Text(
                  "Emergency Report",
                  style: new TextStyle(
                    color: Colors.white,
                    fontSize: MediaQuery.of(context).size.width / 10,
                  ),
                ),
                Card(
                    margin: EdgeInsets.only(top: 30),
                    color: Colors.white,
                    child: Padding(
                      padding: EdgeInsets.all(8.0),
                      child: TextField(
                        controller: emailContent,
                        maxLines: 8,
                        decoration: InputDecoration.collapsed(
                            hintText: "Enter what happened here..."),
                      ),
                    )),
                Container(
                  width: 260,
                  height: 70,
                  padding: EdgeInsets.only(top: 20),
                  child: RaisedButton(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(20.0),
                    ),
                    child: Text(
                      "Send",
                      style: new TextStyle(
                        color: Colors.white,
                        fontSize: 38.0,
                      ),
                    ),
                    color: Colors.grey[850],
                    onPressed: () {
                      if (emailContent.text != "") {
                        sendMail();
                        Navigator.of(context).pop();
                      } else {
                        Fluttertoast.showToast(
                          msg: "You need to put a message!",
                          gravity: ToastGravity.CENTER,
                        );
                      }
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
代码语言:javascript
复制
void getEmailCredentialsF() {
  print("Attemping to get email!");
  final firestoreInstance = FirebaseFirestore.instance;
  FirebaseAuth auth = FirebaseAuth.instance;
  String uid = auth.currentUser.uid.toString();
  firestoreInstance.collection("SendMailCredentials").doc("w1HsHFRgq7Oc3X9xUEnH").get().then((value) {
    EmergencyReport.getEmailCredentials((value.data()["email"]),(value.data()["password"]));
  });
}

有没有办法让代码在运行其余部分之前等待从数据库中收集到的信息?我尝试过等待、异步和未来的构建器(可能用错了,我对flutter还是个新手)

感谢你给予的所有帮助

UI的图片,如果它有助于UI

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-12 17:20:17

昨天我已经回答了你这个问题

代码语言:javascript
复制
FutureBuilder<DocumentSnapshot>(
          future: firestoreInstance.collection("Users").doc(uid).get(),
          builder: (_,snap){
          return snap.hasData ? Text(snap.data.data()["firstName"]):CircularProgressIndicator();
        },)

现在实现相同的方法,比如你有一个对象,你从UI中保留了它

代码语言:javascript
复制
class MyDB{
 //...
}

并且您需要获取用户集合中的文档

代码语言:javascript
复制
class MyDB{
  MyDB();
  Map<String,dynamic> userData;
  
  Future<void> getUser() async {
    userData = //...set
  }
}

你还想要别的东西

代码语言:javascript
复制
class MyDB{
  MyDB();
  Map<String,dynamic> userData;
  Map<String,dynamic> someThingElse;

  Future<void> getUser() async {
    userData = //...set
  }
  Future<void> getSomeThingElse() async {
    someThingElse = //...set
  }
}

您想要等待所有这些数据可用,然后再显示任何内容

代码语言:javascript
复制
class MyDB{
  MyDB();
  Map<String,dynamic> userData;
  Map<String,dynamic> someThingElse;

  Future<void> getUser() async {
    userData = //...set
  }
  Future<void> getSomeThingElse() async {
    someThingElse = //...set
  }
  
  Future getEveryThing() async {
    await getUser();
    await getSomeThingElse();
  }
}

现在在UI中使用getEverything未来

代码语言:javascript
复制
final myDB = MyDB();
build(){
  return FutureBuilder<bool>(
    future: myDB.getEveryThing(),
    builder: (_,snap){
      if(snap.hasData){
        //myDB.userData and myDB.someThingElse will not be null
      }
      //if we are still waiting for the data
      return CircularProgressIndicator();
    },);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64798049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档