About Swift Firestore Result

Asked 2 years ago, Updated 2 years ago, 54 views

I am worried about the following error handling in the Firestore document.
https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja

let docRef=db.collection("cities").document("BJ")

docRef.getDocument {( document, error) in
    // Construct a Result type to encapsulate deserialization errors or
    // successful deserialization.Note that if there is no error brown
    // the value may still be `nil`, indicating a successful deserialization
    // of a value that does not exist.
    //
    // There are three cases to handle, which Swiftlets us describe
    // nice with build-in Result types:
    //
    //      Result
    //        /\
    //   Error Optional <City>
    //               /\
    //            Nil City
    let result = Result {
      try document?.data(as:City.self)
    }
    switch result {
    case.success(let city):
        iflet city=city{
            // A`City`value was successfully initialized from the DocumentSnapshot.
            print("City:\(city)")
        } else{
            // Anil value was successfully initialized from the DocumentSnapshot,
            // or the DocumentSnapshot was nil.
            print("Document does not exist")
        }
    case.failure(let error):
        // A`City`value could not be initialized from the DocumentSnapshot.
        print("Error decoding city:\(error)")
    }
}

Where did the result come from among the above?
Also, I don't understand why this Result is optional in let.

In my opinion, if you process the result for the document as an argument
Apart from the successful document, I don't know why I'm using Result.
If you look at the other code, you are using document as a success.

I look forward to your kind cooperation.

swift firebase

2022-09-30 18:07

2 Answers

Where did the result come from?

Result is the type contained in the Swift standard library.
Result

As in the past, two variables are used to "return non-nil values to result for success, and nil for error.In the case of failure, put nil in result and error in non-nil values" commitment assumes that both result and error cannot be nil on Swift's type system.

Result is followed by the following initializer:

init(catching:)

This initializer generates Result.failure(...) when Error is thrown in the closure and Result.success(...) when a return value is returned without ending the error.

I don't understand why this Result is optional in let.

let appears in several places in your code, so if you clarify which part you are referring to, it will be easier to get a more accurate answer.

We assume that this is the case.success(let city) part.

What we are testing here is whether try document?.data(as:City.self) threw a Error. document is optional, so data(as:) results from data(as:) without calling the method.

Apart from the successful document, I don't know why I'm using Result.

It's a good example not to think that the original code is very hard to see (it's a code published by Google all over the world, so it's written in a good way).It's partly because of this, but it doesn't seem to be fully understood where the success/failure is determined.

  • getDocument Success/Fail

    Success: document is non-nil, error is nil
    Failed: document is nil, error is non-nil

  • data(as:)Success/Failure

    Success:result has a value of .success(City?)
    Failed: result has a value of .failure(Error)

    この Success in this case includes cases where document is not called data(as:) because of nil

getDocument Success/Fail

Success: document is non-nil, error is nil
Failed: document is nil, error is non-nil

data(as:)Success/Failure

Success:result has a value of .success(City?)
Failed: result has a value of .failure(Error)

この Success in this case includes cases where document is not called data(as:) because of nil

In other words, if getDocument itself fails and document contains nil.

At the very least, if you want to use the code to express clearly that you are checking where and what kind of errors are occurring, the code you listed is not a passing point.

For example, would writing like this make it a little easier to understand?

let docRef=db.collection("cities").document("BJ")

        docRef.getDocument {( document, error) in
            iflet error = error {
                print(error)
                return
            }
            guardlet document= document else {
                print("Document does not exist")
                return
            }
            do{
                let city=try document.data(as:City.self)
                print("City:\(city)")
            } catch{
                print("Error decoding city:\(error)")
            }
        }


2022-09-30 18:07

Normally, if you don't have data, nil can fail, if you have data, it can be successful, but I think you use Result to consider things like communication failure, decoding failure to City, etc.

Result itself is a Swift standard feature and is one of the same exception handling as try-catch.


2022-09-30 18:07

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.