本文介绍了及时从Firestore检索数据(在Widget build(BuildContext context)之外)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您希望获得一些背景信息,我在此处提出了类似的问题.在我的Flutter应用中,您可以发送电子邮件

If you would like some context I asked a similar question here. In my flutter app you are able to send emails

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

如上所示.我知道存储电子邮件和密码可能不是最好的方法,但是它可以工作(如果数据及时到位,它将可以工作).所以我的问题是,我将在应用程序的开头运行此功能,但有时无法按时加载.

As seen above. I know it's probably not the best to store the email and password but it works (well it would work if the data came in time). So my problem is I'll run this function at the beginning of the app but sometimes it won't load in on time.

UI代码:

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,
                        );
                      }
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
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"]));
  });
}

是否有一种方法可以让代码在运行其余代码之前等待从数据库收集该信息?我已经尝试过await和async以及未来的构建器(可能是我误以为是错误的,我才刚刚起步)

Is there a way to make the code wait for that information to be gathered from the db before running the rest? I've tried await and async and future builders (could have used them wrong I am fairly new to flutter)

感谢您提供的所有帮助

UI的图片,如果有帮助的话 UI

Pic of UI if it helps UI

推荐答案

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

yesterday I've answered you this

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

现在实现类似假设您有一个对象,可以让用户界面保持警惕

now implement the same likeLets say you have a Object which you keep saperate from UI

class MyDB{
 //...
}

您需要在用户集中获取文档

and you need to get document in users collection


class MyDB{
  MyDB();
  Map<String,dynamic> userData;
  
  Future<void> getUser() async {
    userData = //...set
  }
}

您还想得到其他东西


class MyDB{
  MyDB();
  Map<String,dynamic> userData;
  Map<String,dynamic> someThingElse;

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

,您想要在显示任何内容之前等待所有这些数据可用

and you want to wait for all these data to be available before you show anything


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未来

now use that getEverything future in UI


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

这篇关于及时从Firestore检索数据(在Widget build(BuildContext context)之外)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-25 04:58