jo1995
jo1995

Reputation: 414

How to load datas not in realtime in firebase?

I have the following problem to solve:

enter image description here

All datas are loaded in realtime (this time even multiple times per post), but I just want to refresh with a refresher I already have.

This is my refresher:

// Refresher
func refresh() {
    refresher = UIRefreshControl()
    refresher.attributedTitle = NSAttributedString(string: "Aktualisieren")
    refresher.addTarget(self, action: #selector(DiscoveryViewController.refreshData) , for: UIControl.Event.valueChanged)
    tableView.addSubview(refresher)
}

@objc func refreshData(sender: Any) {
    loadTopPosts()
    refresher.endRefreshing()
}

And with this I load all posts:

func loadTopPosts() {
    ProgressHUD.show("Lade...", interaction: false)
    self.postArray.removeAll()
    self.tableView.reloadData()

    // Aktuelle Location des aktuell eingeloggten Users laden
    guard let currentUserUid = UserApi.shared.CURRENT_USER_ID else { return }
    let databaseRef = LocationApi.shared.geoRef
    databaseRef.getLocationForKey(currentUserUid) { (location, error) in
        if error != nil {
            ProgressHUD.showError("Posts konnten nicht geladen werden")
        } else if location != nil {
            print("Location for \(currentUserUid) is [\(location!.coordinate.latitude), \(location!.coordinate.longitude)]")

            // Alle Posts im vorgegebenen Umkreis laden
            let REF_GEO_POSTS = Database.database().reference().child("geolocation_posts")
            let geoRef = GeoFire(firebaseRef: REF_GEO_POSTS)
            // Lade den aktuell eingestellten Radius aus der Datenbank
            self.observeRadius(completion: { (radius) in
                let currentRadius = radius
            // Üperprüfe, welche Posts im Umkreis erstellt wurden
                let circleQuery = geoRef.query(at: location!, withRadius: Double(currentRadius)!)

            circleQuery.observe(.keyEntered, with: { (postIds, location) in

                self.observePost(withPostId: postIds, completion: { (posts) in
                    guard let userUid = posts.uid else { return }
                    self.observeUser(uid: userUid, completion: { (users) in
                        let postArray = UserPostModel(post: posts, user: users)
                        self.postArray.append(postArray)
                        self.postArray.sort(by: {$0.post!.secondsFrom1970! > $1.post!.secondsFrom1970!})
                        self.tableView.reloadData()
                        self.tableView.setContentOffset(CGPoint.zero, animated: true)
                        ProgressHUD.dismiss()

                    })
                })

                })
            })
            if self.postArray.count == 0 {
                ProgressHUD.dismiss()
            }
        } else {
            ProgressHUD.showError("Posts konnten nicht geladen werden")
        }
    }
}

Here are the functions where I over serve datas from firebase:

let REF_POSTS = Database.database().reference().child("posts")
func observePost(withPostId id: String, completion: @escaping (PostModel) -> Void) {
    REF_POSTS.child(id).observeSingleEvent(of: .value) { (snapshot) in
        guard let dic = snapshot.value as? [String: Any] else { return }
        let newPost = PostModel(dictionary: dic, key: snapshot.key)
        completion(newPost)
    }
}

let REF_USERS = Database.database().reference().child("users")
func observeUser(uid: String, completion: @escaping (UserModel) -> Void) {
    REF_USERS.child(uid).observeSingleEvent(of: .value) { (snapshot) in
        guard let dic = snapshot.value as? [String: Any] else { return }
        let newUser = UserModel(dictionary: dic)
        completion(newUser)
    }
}

func observeRadius(completion: @escaping (String) -> Void) {
    guard let currentUserUid = UserApi.shared.CURRENT_USER_ID else { return }
    let REF_RADIUS = Database.database().reference().child("users").child(currentUserUid).child("radius")
    REF_RADIUS.observeSingleEvent(of: .value) { (radius) in
        let currentRadius = radius.value as? String
        completion(currentRadius!)
    }
}

What I now want to do is to disable the realtime function (updating the tableView only if I refresh). So if I refresh, everything will be displayed correctly.

How to solve this problem?

Thanks in advance for your help!

Upvotes: 1

Views: 44

Answers (1)

Gustavo Vollbrecht
Gustavo Vollbrecht

Reputation: 3256

There is observe, that keeps notifying every time an update happens in the database. And there is observeSingleEvent, that will only provide you data when requested.

https://firebase.google.com/docs/database/ios/read-and-write

And also, your geofire reference will keep notifying you for every update, if you don't want it to do that, remove it like this:

"If you're not interested in getting updates on new/moving users after the initial query, this is also a great moment to remove your observer by calling removeObserverWithFirebaseHandle or removeAllObservers."

in your case it's posts, and that was mentioned here: https://stackoverflow.com/a/50722984/8869493

Upvotes: 1

Related Questions