Reputation: 164
Update 2:
Got this thing to work. Not as elegant as I expected, but works.
The final func is this:
func fetchData(completion: @escaping ([MyModel]?) -> Void) {
self.db
.collection("data/userData")
.order(by: "modified", descending: true)
.addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("no documents \(String(describing: error))")
completion(nil)
return
}
let result = documents.compactMap { queryDocumentSnapshot -> MyModel? in
return try? queryDocumentSnapshot.data(as: MyModel.self)
}
completion(result)
}
}
Calling it like this:
fetchData() { arr in if arr != nil {
//Attach it to vars or whatever
}}
I'm accepting @workingdog answer.
Update 1: Edit: Following @workingdog comment, I tried using this code:
func fetchMyData(completion: @escaping ([MyModel]?) -> Void) {
self.db
.collection("data/userData")
.order(by: "modified", descending: true)
.addSnapshotListener { [self] querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("no documents \(String(describing: error))")
completion(nil)
return
}
let result = documents.compactMap { queryDocumentSnapshot -> MyModel? in
return try? queryDocumentSnapshot.data(as: MyModel.self)
}
completion(result)
}
}
This does still not give me a solution as I'm trying to call this method from a different function but it crashes my app. But also, I only wanted to call it with "var myDocuments = fetchData()". The above code doesn't give me that (although I'm not even sure what I'm asking is possible).
I have this code/query that should return documents from Firestore:
func fetchMyData() {
self.db
.collection("data/userData")
.order(by: "modified", descending: true)
.addSnapshotListener { [self] querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("no documents \(String(describing: error))")
return
}
print(documents.compactMap { (queryDocumentSnapshot) -> MyModel? in
return try? queryDocumentSnapshot.data(as: MyModel.self)
})
}
}
I want this function to return the results instead of printing them. I tried to push them into a high-level variable (self.myDocuments) but this is no good when the project becomes bigger and lots of other functions try to run this query for their own needs.
I tried using:
return documents.compactMap { (queryDocumentSnapshot) -> MyModel? in
return try? queryDocumentSnapshot.data(as: MyModel.self)
}
But got this error message:
Unexpected non-void return value in void function
I understand that 'compactMap' can't return anything, but what else can I do to grab these documents and have 'fetchMyData' to return them?
Upvotes: 0
Views: 328
Reputation: 36119
if "I want this function to return the results instead of printing them." means you expect one MyModel, then try something like this:
EDIT: returning an optional array of MyModel:
func fetchMyData(completion: @escaping ([MyModel]?) -> Void) {
self.db
.collection("data/userData")
.order(by: "modified", descending: true)
.addSnapshotListener { [self] querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("no documents \(String(describing: error))")
completion(nil)
return
}
let result = documents.compactMap { queryDocumentSnapshot -> MyModel? in
return try? queryDocumentSnapshot.data(as: MyModel.self)
}
completion(result)
}
}
use it like this:
fetchMyData() { results in
if let modelArray = results {
// do something with your [MyModel] modelArray
}
}
Upvotes: 2