-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Description
[REQUIRED] Step 1: Describe your environment
- Xcode version: 13.2.1
- Firebase SDK version: 8.10.0
- Installation method: Swift Package Manager
- Firebase Component: Firestore
- Target platform(s): iOS 15.2
[REQUIRED] Step 2: Describe the problem
Steps to reproduce:
- Start a transaction using the following async declaration of
db.runTransaction()
:
func runTransaction(_ updateBlock: @escaping (Transaction, NSErrorPointer) -> Any?) async throws -> Any
- Successfully perform the transaction, without encountering or returning an error (i.e., leave
error?.pointee
unset). return nil
at the end of the transaction update block, as demonstrated in the basic transaction example in the documentation.
Expected result: the transaction is completed with a nil return value.
Actual result: the error Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
is encountered in functional
line 1885.
Partial stack trace:
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x0000000185918d7c in _swift_runtime_on_report ()
#1 0x0000000185998e54 in _swift_stdlib_reportFatalErrorInFile ()
#2 0x00000001855ce1a8 in closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) ()
#3 0x00000001855cdf48 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) ()
#4 0x00000001855cd83c in _assertionFailure(_:_:file:line:flags:) ()
#5 0x00000001855ce254 in _diagnoseUnexpectedNilOptional(_filenameStart:_filenameLength:_filenameIsASCII:_line:_isImplicitUnwrap:) ()
#6 0x0000000104866e3c in @objc completion handler block implementation for @escaping @callee_unowned @convention(block) (@unowned Swift.AnyObject?, @unowned NSError?) -> () with result type Any ()
#7 0x0000000104ca95e8 in std::__1::__function::__value_func<void (firebase::firestore::util::Status)>::operator()(firebase::firestore::util::Status&&) const [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/functional:1885
#8 0x0000000104ca95d0 in std::__1::function<void (firebase::firestore::util::Status)>::operator()(firebase::firestore::util::Status) const [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/functional:2560
#9 0x0000000104ca95d0 in firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()::operator()() const [inlined] at /Users/ionothanus/Library/Developer/Xcode/DerivedData/Detour_On_Route-agyrglamqsjpfrcxugnkspranqcq/SourcePackages/checkouts/firebase-ios-sdk/Firestore/core/src/core/firestore_client.cc:502
#10 0x0000000104ca95b8 in decltype(std::__1::forward<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()&>(fp)()) std::__1::__invoke<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()&>(firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()&) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/type_traits:3694
#11 0x0000000104ca95b8 in void std::__1::__invoke_void_return_wrapper<void, true>::__call<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()&>(firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()&) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/__functional_base:348
#12 0x0000000104ca95b8 in std::__1::__function::__alloc_func<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'(), std::__1::allocator<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()>, void ()>::operator()() [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/functional:1558
#13 0x0000000104ca95b8 in std::__1::__function::__func<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'(), std::__1::allocator<firebase::firestore::core::FirestoreClient::Transaction(int, std::__1::function<void (std::__1::shared_ptr<firebase::firestore::core::Transaction>, std::__1::function<void (firebase::firestore::util::Status)>)>, std::__1::function<void (firebase::firestore::util::Status)>)::$_1::operator()(firebase::firestore::util::Status) const::'lambda'()>, void ()>::operator()() at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/functional:1732
#14 0x0000000104d6b644 in std::__1::__function::__value_func<void ()>::operator()() const [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/functional:1885
#15 0x0000000104d6b630 in std::__1::function<void ()>::operator()() const [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/functional:2560
#16 0x0000000104d6b630 in firebase::firestore::util::Task::ExecuteAndRelease() at /Users/ionothanus/Library/Developer/Xcode/DerivedData/Detour_On_Route-agyrglamqsjpfrcxugnkspranqcq/SourcePackages/checkouts/firebase-ios-sdk/Firestore/core/src/util/task.cc:102
#17 0x00000001061ca3b4 in _dispatch_client_callout ()
#18 0x00000001061da898 in _dispatch_main_queue_callback_4CF ()
#19 0x0000000180b95d84 in __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ ()
#20 0x0000000180b4ff5c in __CFRunLoopRun ()
#21 0x0000000180b63468 in CFRunLoopRunSpecific ()
#22 0x000000019c70738c in GSEventRunModal ()
#23 0x00000001835065d0 in -[UIApplication _run] ()
#24 0x0000000183284f74 in UIApplicationMain ()
#25 0x0000000188822314 in closure #1 in KitRendererCommon(_:) ()
#26 0x0000000188751508 in runApp<τ_0_0>(_:) ()
#27 0x0000000188732cb8 in static App.main() ()
Relevant Code:
struct SomeCodableObject: Codable, Identifiable {
// your fields here...
@DocumentID var id: String?
}
// authenticate with Firebase, initialize the app, etc., etc.
func updateSubscription(subscription: SomeCodableObject) async throws {
let docRef = db.collection('someCollection').document('someDocument')
let _ = try await db.runTransaction({ transaction, error in
do {
try transaction.setData(from: subscription, forDocument: docRef)
} catch let setError as NSError {
error?.pointee = setError
// In my testing, returning nil here does not seem to be an issue.
return nil
}
// Returning nil here causes the error.
return nil
// Returning a value does not cause the error.
// return subscription
})
}
Workarounds I've found so far:
- return a non-nil value at the end of the successful transaction.
- don't use the
async
declaration. If you want async, wrap the continuation yourself with awithCheckedThrowingContinuation()
wrapper.