Firebase 在QuerySnapshot火基颤振自动增长列表的ForEach循环中进行计算,会导致错误的计算-错误的结果
我正在迭代一个querysnapshot,获取我用来计算距离的值。计算公式在for循环外进行了良好的测试。值/变量不为null(已完成null检查)。每次计算都会将计算出的数据迭代地传递到列表中。日志显示,对于每个完整的循环,列表中的数据都会加倍—例如,第一个循环的items count为60返回60次计算,第二次刷新输出为120—类似于此,或者根据加载的项目数随机增加。其次,计算是错误的。虽然这是一种基于等待和同步的方法,但我无法找出错误答案的原因以及如何删除重复项。在每次计算之前(在foreach循环之前),我确实会清除列表。 见下面的代码:Firebase 在QuerySnapshot火基颤振自动增长列表的ForEach循环中进行计算,会导致错误的计算-错误的结果,firebase,flutter,dart,Firebase,Flutter,Dart,我正在迭代一个querysnapshot,获取我用来计算距离的值。计算公式在for循环外进行了良好的测试。值/变量不为null(已完成null检查)。每次计算都会将计算出的数据迭代地传递到列表中。日志显示,对于每个完整的循环,列表中的数据都会加倍—例如,第一个循环的items count为60返回60次计算,第二次刷新输出为120—类似于此,或者根据加载的项目数随机增加。其次,计算是错误的。虽然这是一种基于等待和同步的方法,但我无法找出错误答案的原因以及如何删除重复项。在每次计算之前(在fore
Future<List> getDistancesModified() async {
distanceList.clear();
var x = await FirebaseFirestore.instance.collection(Str.ITEMS).get();
if (x != null) {
x.docs.forEach((doc) {
itemAddressLat =
double.tryParse(doc.data()[Str.ITEM_LATITUDE].toString()) ??
-1.2921;
itemAddressLong =
double.tryParse(doc.data()[Str.ITEM_LONGITUDE].toString()) ??
36.8219;
distance = distanceBetween(
itemAddressLat ?? defaultUserLat,
itemAddressLong ?? defaultUserLong,
usersCurrentLocationLat ??
usersCurrentLocationLatFromDb ??
defaultUserLat,
usersCurrentLocationLong ??
usersCurrentLocationLongFromDb ??
defaultUserLong); //gives wrong answer inside the foreach loop but gives right answer if done separate from the for each loop for single values. The foreach is necessary to get all distances and pass them to a text through a future builder.
distance = distance.roundToDouble();
distanceList.add(formatDistance(distance / 1000));//console prints grows for every rebuild
});
}
文本上显示的值是错误的,例如,当预期输出为200米或3公里时,实际不可能给出1113公里、4096公里等。计算仅在for each循环中进行
任何帮助都将不胜感激。这正在扼杀我的应用程序。这个问题困扰了我一段时间,但下面的代码起了作用:
Future<List> getDistances() async {
distanceList = [];
for (var i in items) {
var s;
var x = i.data()[Str.ITEM_LATITUDE].toString();
var y = i.data()[Str.ITEM_LONGITUDE].toString();
double d = distanceBetween(
double.tryParse(x) ?? usersDefaultCityLat,
double.tryParse(y) ?? usersDefaultCityLong,
usersCurrentLocationLat ??
usersHomeLocationLat ??
usersDefaultCityLat,
usersCurrentLocationLong ??
usersHomeLocationLong ??
usersDefaultCityLong);
if (d < 454) {
s = "Nearby";
}
if (d >= 454 && d < 1000) {
d = d;
s = d.toStringAsFixed(0) + " M";
}
if (d >= 1000) {
s = (d / 1000).toStringAsFixed(0) + " KM";
}
distanceList.add(s);
}
return distanceList;
}
FutureBuilder(
future: getDistances(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
distanceList.length >
index
? distanceList[index]
.toString()
: "",//THIS CHECK WAS NECESSARY AGAINST LIST LENGHTS NOT MATCHING IF ANY
style: TextStyle(
color: Colors.black,
fontSize: 12.0,
fontWeight:
FontWeight.w600),
);
} else {
return Icon(Icons
.location_searching);
}
},
),
1.您试过调试它吗?2.一个可能的问题是,如果在进行中有一个较早的调用时再次调用
getDistancesModified
,两个调用都会添加到相同的distanceList
(在这种情况下,第二个调用调用distanceList.clear()
没有帮助;它将清除一个已空的列表。)或者移动清除()
在wait
之后调用to be,这样清除列表并添加到列表中就不会被中断,或者最好尽可能使用局部变量。你能发布调试输出吗?看看第3、5、9-68行以及第70和72行,其余都是重复的-只要重新启动应用程序,就好像getDistancesModified()被调用14次以上-请注意,getDistancesModified()的唯一引用位置是将来在for distance.File中显示文本的位置如下:
Future<void> setUserLocationAddress() async {
await getLocationFromLocationPackage();
await setCountryCapitalCityLatlong();
await getUserHomeAddress();
await getDistances();
@override
void initState() {
super.initState();
setUserLocationAddress();
}
FutureBuilder(
future: getDistances(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
distanceList.length >
index
? distanceList[index]
.toString()
: "",//THIS CHECK WAS NECESSARY AGAINST LIST LENGHTS NOT MATCHING IF ANY
style: TextStyle(
color: Colors.black,
fontSize: 12.0,
fontWeight:
FontWeight.w600),
);
} else {
return Icon(Icons
.location_searching);
}
},
),