Firestore事务读取失败:文档不存在时报nilError问题咨询
Great question! Let me clarify this upfront: You absolutely can complete a Firestore transaction even when the target document doesn't exist—the nilError you're seeing isn't a restriction from Firestore itself, but likely a small issue in your code implementation.
Firestore's transaction getDocument method doesn't throw an error when the requested document is missing. Instead, it returns a DocumentSnapshot where:
- The
existsproperty isfalse - The
data()method returnsnil
Your nilError is probably coming from a different source (like uninitialized variables or unexpected runtime issues) rather than the missing document itself.
Here's a revised, robust version of your code that properly handles missing documents and fixes potential nil-related bugs:
let db = Firestore.firestore() // Reuse the document reference to avoid typos and redundant code let targetDocRef = db.document("path/nestedPath") db.runTransaction({ (transaction, errorPointer) -> Any? in do { // This won't throw if the document doesn't exist—only for real errors like network issues let document = try transaction.getDocument(targetDocRef) if document.exists { // Document exists: update existing fields transaction.updateData(["x": y], forDocument: targetDocRef) } else { // Document doesn't exist: create it with full data transaction.setData(["x": z], forDocument: targetDocRef) } return nil } catch let fetchError as NSError { // Catch genuine failures (permissions, network timeouts, etc.) errorPointer?.pointee = fetchError return nil } }) { (object, error) in if let error = error { print("Transaction Completion Error: \(error)") } else { print("Transaction Succeeded!") } }
Key Fixes & Explanations:
- Reused document reference: Storing
targetDocRefas a variable eliminates duplicate path strings, reducing typos and making the code cleaner. - Explicit existence check: Using
document.existsis a more readable way to verify if the document exists, compared to checkingdata()(though both work). - Fixed variable initialization: Removed the uninitialized
var document: DocumentSnapshotdeclaration, which was likely contributing to your nil-related errors. We now declare and assign the snapshot directly in thedoblock. - Clear error handling: The
catchblock only handles actual failures (network issues, permission denied, etc.)—not the expected case of a missing document.
One more important note: Firestore transactions are built to handle concurrent writes seamlessly. Even if another client creates the document between your read and write operations, the transaction will automatically retry to ensure data consistency—this works whether the document existed initially or not.
内容的提问来源于stack exchange,提问作者Chris

