从firebase加载到tableview的问题

时间:2018-05-01 11:00:48

标签: swift firebase firebase-realtime-database tableview geofire

我的应用程序的目标是找到附近的Warhammer 40k玩家。用户的坐标保存在名为Locations的分支中,该分支有4个子分支; “初学者”,“好”,“行家”,“精英”

将密钥(用户的uid)获取到附近的坐标后,系统应该通过密钥列表(称为distanceArray)获取有关用户的信息。之后,此信息应显示在tableView

应该显示的关于附近玩家的信息应该是:个人资料图片,姓名,平均评分和评分数量(这些存储在第三个不同的分支中)和距离你的距离

  1. 当我在viewDidLoad()中运行fetchNearbyLocations时,我没有在名为array的{​​{1}}中获得任何结果。在我重新加载distanceArray 2次之前,我没有得到任何结果。我如何在一开始就获取所有用户?

  2. 当我使用我设置的重新加载按钮时,我会获得已经存在的用户的多个副本。

  3. 重要代码:

    结论和设置

    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
            }
        )}
    

1 个答案:

答案 0 :(得分:1)

Firebase请求是异步的。这意味着您应该在请求完成后重新加载Tableview并从Firebase获得响应。最简单的方法是在self.tableView.reloadData()

中调用func fetchNearbyLocations (userID: String, dbPath: String)