Why I couldn't assign fetched values from Fire

2019-09-21 15:24发布

I tried several times with various ways to assign the collected values of documents from firestore into an array. Unfortunately, I could't find a way to solve this issue. I attached the code that I recently tried to implement. It includes before Firestore closure a print statement which print the whole fetched values successfully. However, after the closure and I tried to print the same array and the result is an empty array.

I tried to implement this code

var hotelCities: [String] = []

func getCities() {
    db.collection("Hotels").getDocuments() { (querySnapshot,  err) in
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            for document in querySnapshot!.documents {
                var found = false
                let documentDetails = document.data() as NSDictionary
                let location = documentDetails["Location"] as! NSDictionary
                let city = location["city"]!
                if (self.hotelCities.count == 0) {
                    self.hotelCities.append(String(describing: city))
                }
                else{
                    for item in self.hotelCities {
                        if item == String(describing: city){
                            found = true
                        }
                    }
                    if (found == false){
                        self.hotelCities.append(String(describing: city))
                    }
                }
            }
        }
        print(self.hotelCities)
    }
    print(self.hotelCities)
}

1条回答
相关推荐>>
2楼-- · 2019-09-21 16:08

That's actually the expected result, since data is loaded from Firestore asynchronously.

Once you call getDocuments(), the Firestore client goes of and connects to the server to read those documents. Since that may take quite some time, it allows your application to continue running in the meantime. Then when the documents are available, it calls your closure. But that means the documents are only available after the closure has been called.

It's easiest to understand this flow, by placing a few print statements:

print("Before starting to get documents");
db.collection("Hotels").getDocuments() { (querySnapshot,  err) in
  print("Got documents");
}
print("After starting to get documents");

When you run this code, it will print:

Before starting to get documents

After starting to get documents

Got documents

Now when you first saw this code, that is probably not the output your expected. But it completely explains why the print(self.hotelCities) you have after the closure doesn't print anything: the data hasn't been loaded yet.

The quick solution is to make sure that all code that needs the documents is inside of the close that is called when the documents are loaded. Just like your top print(self.hotelCities) statement already is.

An alternative is to define your own closure as shown in this answer: https://stackoverflow.com/a/38364861

查看更多
登录 后发表回答