I have a simple Firestore transaction that reads to verify the existence of a document first, and if it doesn't exist, does some write operations.
Code snippet looks something like this
Firestore.firestore().runTransaction({ (transaction, errorPointer) -> Void in
let snapshot: DocumentSnapshot
// First check if user already exists.
let userRef = firestore.document("users/\(user.uid)")
do {
try snapshot = transaction.getDocument(userRef)
} catch let fetchError as NSError {
errorPointer?.pointee = fetchError
return
}
if !snapshot.exists {
// Document doesn't exist. Start write operation...
...
It seems that getDocument does not return a valid snapshot when the document doesn't exist and instead throws an error. I don't want to rely on the error to conclude that the doc doesn't exist (as it can get muddled with other errors).
What would be the proper way to verify a document's existence within a Firestore transaction?
Well, you can try doing something like this:
Firestore.firestore().runTransaction({ (transaction, errorPointer) -> Void in
let snapshot: DocumentSnapshot
if let snapshot = try? transaction.getDocument(userRef) {
if snapshot.exists {
// Snapshot already exists!
return
}
}
print("Document doesn't exist. Let's get to work!")
// Perform write operations here
...
Although depending on what you're looking to do, it might be easier to enforce this with security rules.
For example, the following rules will allow you to create a new user object, but never overwrite it.
match /users/{userID} {
allow create: if request.auth.uid == userID;
allow update: if false;
}
Then you could just try to set the user object every time, and it would only succeed the first time. But, obviously, this only works if you never actually want your client to update the user object in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With