我正在制作一个颤振应用程序,并且我正在使用 cloud firestore 作为我的在线数据库。我的应用程序中的一项功能是寻找附近的用户,并在屏幕上的自定义小部件中向当前用户显示他们的个人资料。我这样做的方式是获取当前用户的位置(实时位置或保存在数据库中的地址),然后为用户遍历我的数据库集合中的每个用户。我从存储的数据中获取用户的地址,使用距离矩阵 API 计算距离,然后如果距离小于特定数字(例如 10000 米),我为用户创建配置文件小部件以在屏幕上显示它。
有2个问题:
1-如果我的用户数量增加(例如一百万用户),通过查看每个用户详细信息并计算距离,可能需要很长时间才能在屏幕上获得结果。目前,我只有 20 个用户用于测试目的,当我搜索附近的用户时,结果可能需要 30 秒才能显示在屏幕上。
2- 由于互联网连接速度较慢,等待时间可能会更长,并且它可以使用大量用户数据来完成这个简单的任务。
如何改进此功能并使其更快?
(我目前的想法是根据用户的位置将用户划分为不同的文档,然后使用当前用户的位置仅浏览其中一个文档。问题是如何有效地划分地址并找到要查找的最佳地址为了。)
下面是我找到附近用户并将他们添加到我传递给我的自定义小部件类的列表的代码。
final List<UserBoxDesign> listOfBoxes = [];
final FirebaseUser currentUser = await auth.currentUser();
final String currentUserId = currentUser.uid;
if (_userLocationSwitchValue == false) { //use default address of the user
currentUserAddress = await _databaseManagement.getUserCollectionValues(
currentUserId, "address");
} else {
//currentUserAddress = //to do, get device location here.
}
if (_searchValue == SearchValues.Users) {
final List<String> userIds = await _databaseManagement.getUserIds();
for (String id in userIds) {
final String otherUserLocations =
await _databaseManagement.getUserCollectionValues(id, "address");
final String distanceMeters = await _findDistanceGoogleMaps(
currentUserAddress, otherUserLocations);
if (distanceMeters == "Address can't be calculated" ||
distanceMeters == "Distance is more than required by user") {
//if it's not possible to calculate the address then just don't do anything with that.
} else {
final double distanceValueInKilometers = (double.parse(
distanceMeters) /
1000)
.roundToDouble();
final String userProfileImageUrl =
await _databaseManagement.getUserCollectionValues(id, "image");
final String username =
await _databaseManagement.getUserCollectionValues(id, "username");
listOfBoxes.add(
UserBoxDesign( //it creates a custom widget for user if user is nearby
userImageUrl: userProfileImageUrl,
distanceFromUser: distanceValueInKilometers,
userId: id,
username: username,
),
); //here we store the latest values inside the reserved data so when we create the page again, the value will be the reservedData value which is not empty anymore
}
print(listOfBoxes);
}
listOfBoxes.sort((itemA,itemB)=>itemA.distanceFromUser.compareTo(itemB.distanceFromUser)); //SORTs the items from closer to more far from user (we can reverse it to far comes first and close goes last)
setState(() {
_isSearchingForUser = false;
});
return listOfBoxes;
这是我计算原始地址和目标地址之间距离的代码。
Future<String> _findDistanceGoogleMaps(
String originAddress, String destinationAddress) async {
final String url =
"https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=$originAddress&destinations=$destinationAddress&key=$GoogleMapsAPIKey";
try {
final response = await http.get(url);
final responseDecoded = json.decode(response.body);
final distanceInMeters = double.parse(responseDecoded["rows"][0]
["elements"][0]["distance"]["value"]
.toString()); //this is the value in meters always so for km , divide by 1000.
if (distanceInMeters < 100000) {
return distanceInMeters.toString();
} else {
return "Distance is more than required by user";
}
} catch (e) {
return "Address can't be calculated";
}
}