user5715585
user5715585

Reputation:

Passing data to synchronous call in async function

I'm working with firebase and I have a function which returns a promise from a document reference.

func getCatalogItem(ref: DocumentReference) -> Promise<Catalog> {
        return Promise { seal in
        ref.getDocument() { result, err in
            if err != nil {
                seal.reject(err!)
            } else {
                let data = FirestoreDecoder()
                do {
                    let item = try data.decode(Catalog.self, from: result!.data()!)
                    seal.fulfill(item)
                } catch {
                print("Error")
                }
            }
        }
    }
}

It works fine but the only thing is the return type is a custom type which I decoded from the document reference call but the call itself is synchronous and it crashes my app with a nil error because the data isn't actually there yet.

Here's the line and function that produces the error (nil)

let item = try data.decode(Catalog.self, from: result!.data()!)

I tried making another function with a handler for the firebase function and passing that value to the decoder but that also returned nil, and (I'm using awaitkit/promisekit) I tried messing around with async/await but couldn't get that to work. How could I fix this?

Screenshot of the document in my database: screenshot of the document I'm trying to access

and then i have this:

let featureditem = Firestore.firestore().collection("catalog").document("TDS faded jeans")
self.featureditem.getDocument() { doc, err in
                            if doc == doc {
                                let item = try! FirestoreDecoder().decode(Catalog.self, from: doc!.data()!)
                                print("\(item)")

Which is also giving me nil.

Upvotes: 0

Views: 380

Answers (2)

user5715585
user5715585

Reputation:

An unusual error where the particular document I was trying to access would return a nil value but trying with another document fix the problem, it may be because I named a field wrong and ended up deleting it and creating a new field with the correct name, but there's no way to truly know.

Upvotes: 1

Doug Stevenson
Doug Stevenson

Reputation: 317382

You need to check if data() can return nil, since that's what it returns when there's no document found. According to the linked API documentation:

Retrieves all fields in the document as an NSDictionary. Returns nil if the document doesn’t exist.

Either that, or check exists before assuming there's data.

Upvotes: 1

Related Questions