颤振Firebase数据库变量在方法后未接收值

颤振Firebase数据库变量在方法后未接收值,firebase,flutter,dart,mobile,google-cloud-firestore,Firebase,Flutter,Dart,Mobile,Google Cloud Firestore,我正在构建一个方法,其中信息是从Firebase(Cloud Firestore)读取的,但是调用时没有将值分配给变量,有人能帮忙吗 testt变量只是用来测试方法是否正在被调用和运行,但我无法理解为什么其他变量没有得到任何值 class _VehicleDetailsState extends State<VehicleDetails> { String speed, place, testt; void displayData() { testt = "

我正在构建一个方法,其中信息是从Firebase(Cloud Firestore)读取的,但是调用时没有将值分配给变量,有人能帮忙吗

testt变量只是用来测试方法是否正在被调用和运行,但我无法理解为什么其他变量没有得到任何值

class _VehicleDetailsState extends State<VehicleDetails> {
  String speed, place, testt;

  void displayData() {
    testt = "Test";
    FirebaseFirestore.instance
        .collection('Cars')
        .where('id', isEqualTo: Routes.idCar)
        .get()
        .then((value) {
      value.docs.forEach((result) {
        place = result.data()['place'];
        speed = result.data()['speed'];
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    displayData();
    print(testt);
    print(place);
    return Scaffold(
      appBar: new AppBar(
        title: new Text(
          'Vehicle Details',
          style:
              new TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
        ),
        leading: IconButton(
          icon: Icon(Icons.arrow_back, color: Colors.white),
          onPressed: () {
            Navigator.of(context).popAndPushNamed(Routes.routeName);
          },
        ),
      ),
    );
  }
}
class\u车辆详细状态扩展状态{
串速、位置、测试时间;
void displayData(){
testt=“Test”;
FirebaseFirestore.instance
.收集(“汽车”)
.where('id',isEqualTo:Routes.idCar)
.get()
.然后((值){
value.docs.forEach((结果){
place=result.data()['place'];
速度=结果.data()['speed'];
});
});
}
@凌驾
小部件构建(构建上下文){
显示数据();
打印(testt);
印刷品(地点);
返回脚手架(
appBar:新的appBar(
标题:新文本(
‘车辆详情’,
风格:
新的文本样式(颜色:Colors.white,fontwweight:fontwweight.bold),
),
领先:IconButton(
图标:图标(Icons.arrow\u back,颜色:Colors.white),
已按下:(){
Navigator.of(context.popandpushname)(Routes.routeName);
},
),
),
);
}
}
Firestore是异步的,这意味着您可以向它询问信息,它会在后台获取信息,而您的代码会继续工作。这就是为什么你的价值观没有改变;因为Firestore在其余代码执行时还没有它们

你可以用两种方法来解决这个问题。使用
wait
关键字或
.then()
方法。猜猜看,你已经在firestore调用中使用了
.then()
方法了!您告诉它获取数据,然后执行您在
.THEN()
回调中输入的任何代码。 `

获取数据的另一种方法是使用
wait
关键字。wait关键字表示“等待此异步函数给我一个值,然后继续执行其余代码”。但是,为了使用wait关键字,它所在的函数也需要是异步的。如果您仔细想想,这是有道理的,因为您不希望在一个web请求上锁定整个代码。如果失败了怎么办?那么你的整个应用程序都被冻结了!下面是一个使用与以前相同类型代码的示例

Future<void> displayData() async {
testt = "test";
   // Waits for firestore to give back the value, then executes the rest of the code.
   dynamic value = await FirebaseFirestore.instance.collection('Cars').where('id', isEqualTo :Routes.idCar).get();
  // The below code only starts once the above code has a value.
     value.docs.forEach((result) {
     place = result.data()['place'];
     speed = result.data()['speed'];
     });
Future displayData()异步{
testt=“test”;
//等待firestore返回值,然后执行其余代码。
动态值=wait FirebaseFirestore.instance.collection('Cars')。其中('id',isEqualTo:Routes.idCar.get();
//下面的代码仅在上面的代码具有值时启动。
value.docs.forEach((结果){
place=result.data()['place'];
速度=结果.data()['speed'];
});
您可能会注意到
Future
过去的位置just
void
。这是一个未来,它是颤振中大多数异步事物的基础。您可以使用wait,然后使用它

对于您的代码,我很抱歉,但是您可能需要重新构造一点以考虑加载数据。您的生成方法不能是异步的,但是您可以从
displayData()
方法对UI进行适当的更改

TL;DR:
它是空的,因为它还没有值。

谢谢你提供了非常详细和解释性的答案,我意识到了我的错误
Future<void> displayData() async {
testt = "test";
   // Waits for firestore to give back the value, then executes the rest of the code.
   dynamic value = await FirebaseFirestore.instance.collection('Cars').where('id', isEqualTo :Routes.idCar).get();
  // The below code only starts once the above code has a value.
     value.docs.forEach((result) {
     place = result.data()['place'];
     speed = result.data()['speed'];
     });