颤振Firebase数据库变量在方法后未接收值
我正在构建一个方法,其中信息是从Firebase(Cloud Firestore)读取的,但是调用时没有将值分配给变量,有人能帮忙吗 testt变量只是用来测试方法是否正在被调用和运行,但我无法理解为什么其他变量没有得到任何值颤振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 = "
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
过去的位置justvoid
。这是一个未来,它是颤振中大多数异步事物的基础。您可以使用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'];
});