简体   繁体   中英

Most efficient way to fetch data from Firebase

I am fetching the current user's friends and storing the users in an array which gets displayed in a collection view. The friends collection view is on my home view controller which means it always remains in the users stack .

My problem is, if the user adds or removes friends via the users profile page and then navigates back to the home view, I have to refetch the data and refresh the collection view in viewWillAppear . This makes the app costly for data and I definitely feel this is not the most efficient way.

I know that Firebase allows me to setup observers, however I am not too sure on the best way to do this without receiving massive loads of data.

Here is the way I currently fetch the user's friends

func fetchFriends() {

    let userID = Auth.auth().currentUser?.uid
    var tempFriend = [UserClass]()

    self.usersArray.removeAll()
    collectionView.reloadData()

    let friendRef = self.databaseRef.child("users").child(userID!).child("Friends")
    friendRef.queryOrderedByKey().observe(.childAdded, with: { (snapshot) in

        let friendID = "\(snapshot.value!)"
        let usersRef = self.databaseRef.child("users")

        usersRef.observeSingleEvent(of: .value, with: { (users) in

            for user in users.children {
                let friend = UserClass(snapshot: user as! DataSnapshot)

                if friendID == friend.uid {
                    tempFav.append(friend)
                }
            }
            self.usersArray = tempFav
            self.collectionView.reloadData()

            if self.usersArray.count == 0 {
                self.noDataLabel.text = "You have no friends!"
                self.noDataLabel.isHidden = false
            } else {
                self.noDataLabel.text = "Loading..."
                self.noDataLabel.isHidden = true
            }
        })
    })
}

This gets called in the user's viewWillAppear

To make this question as clear as possible, what is the best way to refresh the user's friends without needing to fetch the entire list again every time the view appears.

It sounds like you currently remove your observers when the view disappears. At that point Firebase will remove the users data from its memory cache. So indeed when you re-attach the listener in viewWillAppear , the data will need to be reloaded from the Firebase servers.

If you don't want the data to be reloaded, you'll need to make sure that it remains available on the device. There are two options for this:

  1. Ensure the data stays in memory
  2. Ensure the data is persisted to disk

Ensure the data stays in memory

To ensure the data stays in memory, you must keep the observer attached even after the user navigates away from the view. This means that you'll want another class to manage the observer, one that doesn't remove the observer when the user navigates.

The simplest approach for this is to have a global singleton that manages the observers and the user data, eg UserDataManager . When your view first calls this class, create/attach the listener and read the user data. When a subsequent view needs the users, they'll already be loaded in the UserDataManager ready for use.

The main problem with this is that as you do this for more data, you may end up keeping more data in memory than needed. So be aware of memory consumption of such unneeded data, and prune (remove listeners) as needed.

Ensure the data is persisted to disk

A simple way to reduce the amount of data that is downloaded is to =enable disk persistence]( https://firebase.google.com/docs/database/ios/offline-capabilities#section-disk-persistence ) when the app starts.

If disk persistence is enabled, the Firebase client stores data that it recently observed to disk (in addition to keeping any active data in memory). When you attach a new observer and the data isn't in memory yet, Firebase will check the disk cache for that data. If the data exists in the disk cache, it uses that to rebuild its memory cache and performs a much cheaper (bandwidth wise) check against the server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM