moosgrn
moosgrn

Reputation: 379

Firestore Offline Not Updating

I've got a TableView that loads an array from Firestore, however I'm not able to get it to successfully update my view offline. It seems to be saving updates, however not retrieving them.

Here's my attempt at enabling persistence:

//In AppDelegate didFinishLaunching
let settings = FirestoreSettings()
    settings.isPersistenceEnabled = true
    let db = Firestore.firestore()
    db.settings = settings

I save and retrieve data using NSDictionary, then reload the TableView.

//Retrieving from Firestore
func loadTasks() {
    todoList = []
    let db = Firestore.firestore()
    guard let currentUser = Auth.auth().currentUser else {
        return
      }
    // Get tasks by User ID
    db.collection("tasks").whereField("user_id", isEqualTo: currentUser.uid)
        .getDocuments() { (querySnapshot, err) in
            MBProgressHUD.hide(for: self.view, animated: true)
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    let task: Task = self.convertDictionaryToTask(document.data() as NSDictionary)
                    self.taskList.append(task)
                }
               }
              }


//Saving to Firestore
func updateTask(_ task: Task) {
    let db = Firestore.firestore()
    guard let currentUser = Auth.auth().currentUser else {
        return
    }

    let dicTask = convertTaskToDictionary(task)
    // Update a task
    db.collection("tasks").document(currentUser.uid + "_" + task.taskId).updateData([
        "task": dicTask
    ]) { err in
        if let err = err {
            print("Error writing document: \(err)")
        } else {
            print("Document successfully written!")
        }
        self.loadTasks()
    }
}

Thanks!

Upvotes: 0

Views: 679

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

The completion handler for your call to updateData will only be called once the data has been accepted or rejected on the server. Before that, the data will be available client-side in the cache, but your completion handler won't be called, and thus self.loadTasks() will never happen.

You have two options:

  1. Call self.loadTasks() right after calling updateData(...). If updating the local cache fails, the updateData(...) call will raise an error. So if that call doesn't raise an error, the data is saved locally.

    db.collection("tasks").document(currentUser.uid + "_" + task.taskId).updateData([
        "task": dicTask
    ]) { err in
        if let err = err {
            print("Error writing document on server: \(err)")
        } else {
            print("Document successfully written on server!")
        }
    }
    self.loadTasks()
    
  2. Use an onSnapshot listener, instead of getDocuments as shown in the documentation on listening for realtime updates. Such a listener will be called immediately when the local cache has been updated, and possibly again after the server processes the update (for example: if the server rejects it).

Upvotes: 1

Related Questions