我的应用程序的目标是找到附近的Warhammer 40k玩家。用户的坐标保存在名为Locations的分支中,该分支有4个子分支; “初学者”,“好”,“行家”,“精英”。
将密钥(用户的uid)获取到附近的坐标后,系统应该通过密钥列表(称为distanceArray)获取有关用户的信息。之后,此信息应显示在tableView
。
应该显示的关于附近玩家的信息应该是:个人资料图片,姓名,平均评分和评分数量(这些存储在第三个不同的分支中)和距离你的距离
当我在viewDidLoad()
中运行fetchNearbyLocations时,我没有在名为array
的{{1}}中获得任何结果。在我重新加载distanceArray
2次之前,我没有得到任何结果。我如何在一开始就获取所有用户?
当我使用我设置的重新加载按钮时,我会获得已经存在的用户的多个副本。
重要代码:
结论和设置
tableView
//完成阻止
// CompletionBlock以检查用户是否具有用户ID
var ref: DatabaseReference!
var GeoRef: GeoFire!
var users = [userList]()
var distanceArray = [tempDistance]()
let uid = Auth.auth().currentUser?.uid
var dbPath: String = "Beginner"
struct userList {
var name: String?
var databaseKey: String?
var imageUrl: String?
var distance: Double = 0
var avgRating: Double?
var ratingCount: Int?
}
struct tempDistance {
var uid: String?
var distanceToPrint: Double = 0
}
func fetchUsers() {
users.removeAll()
for item in distanceArray{
var name: String?
var databaseKey: String?
var imageUrl: String?
var distance: Double?
var avgRating: Double?
var ratingCount: Int?
checkName(userID: item.uid!, completion: { (success) -> Void in
if success{
let nameRef = self.ref.child("userInfo").child(item.uid!)
nameRef.observeSingleEvent(of: .value) { (snapshot) in
let dictionary = snapshot.value as? [String: AnyObject]
name = (dictionary!["Name"] as? String)!
imageUrl = (dictionary!["profileImage"] as? String)!
databaseKey = item.uid!
distance = item.distanceToPrint
self.users.append(userList(name: name, databaseKey: databaseKey, imageUrl: imageUrl, distance: distance!, avgRating: avgRating, ratingCount: ratingCount))
self.tableView.reloadData()
}
//Add retrieval for avgRating, and ratingCount
self.checkRatings(userID: item.uid!, completion: { (success) -> Void in
if success{
let avgRatingRef = self.ref.child("avgScore").child(item.uid!)
avgRatingRef.observeSingleEvent(of: .value) { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]{
avgRating = (dictionary["Score"] as? Double)!
ratingCount = (dictionary["Count"] as? Int)!
}
print("append 1")
self.users.append(userList(name: name, databaseKey: databaseKey, imageUrl: imageUrl, distance: distance, avgRating: avgRating, ratingCount: ratingCount))
}
} else {
avgRating = 0
ratingCount = 0
print("append 2")
self.users.append(userList(name: name, databaseKey: databaseKey, imageUrl: imageUrl, distance: distance, avgRating: avgRating, ratingCount: ratingCount))
}
})
} else {
print("NAME AND IMAGE HAS NOT BEEN SET")
}
})
}
}
func fetchNearbyLocations (userID: String, dbPath: String) {
var keys = [String]()
var myLoc = CLLocation()
(self.GeoRef.getLocationForKey(userID, withCallback: { (location, error) in
if (error != nil) {
print("An error occured in fetchNearbyLocations: \(String(describing: error?.localizedDescription))")
}
else if (location != nil) {
myLoc = location!
//sets the radius - at 100 km
let circleQuery = self.GeoRef.query(at: myLoc, withRadius: 100.0)
circleQuery.observe(.keyEntered, with: { (key: String, location: CLLocation!) in
let distanceFromUser = myLoc.distance(from: location)
print("DISTANCE: \(distanceFromUser)")
keys.append(key)
self.distanceArray.append(tempDistance(uid: key, distanceToPrint: distanceFromUser))
print(self.distanceArray)
})
}
}))
}
//Reloads the arrays, acts as a refresh
@objc func reloadArray() {
fetchNearbyLocations(userID: uid!, dbPath: dbPath)
fetchUsers()
print(users)
print(distanceArray)
self.tableView.reloadData()
refreshControl.endRefreshing()
}
//sets the GeoRef to the needed value depending on the sorting
@objc func changeGeoRef() {
switch skillSortControl.selectedSegmentIndex {
case 0:
dbPath = "Beginner"
case 1:
dbPath = "Good"
case 2:
dbPath = "Adept"
case 3:
dbPath = "Elite"
default:
dbPath = "Beginner"
}
reloadArray()
GeoRef = GeoFire(firebaseRef: ref.child("Locations").child(dbPath))
}
//表格视图功能
func checkName(userID: String, completion: @escaping ((_ success: Bool) -> Void)){
self.ref.child("userInfo").observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.hasChild(userID){
completion(snapshot.hasChild(userID))
print("USERINFO EXISTS ")
//return true
}else{
print("NO USERDATA EXISTS")
completion(false)
//return false
}
//return result
}
)}
//completion block to check if user has any score, or rating
func checkRatings(userID: String, completion: @escaping ((_ success: Bool) -> Void)){
self.ref.child("avgScore").observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.hasChild(userID){
completion(snapshot.hasChild(userID))
print("THERE EXISTS SOME RATINGS")
//return true
}else{
print("THERE IS NO RATING DATA, SETTING TO DEFAULT 0")
completion(false)
//return false
}
//return result
}
)}
答案 0 :(得分:1)
Firebase请求是异步的。这意味着您应该在请求完成后重新加载Tableview并从Firebase获得响应。最简单的方法是在self.tableView.reloadData()
func fetchNearbyLocations (userID: String, dbPath: String)