I am using Android client to create new document.
Map<String, Object> city = new HashMap<>();
city.put("name", "Los Angeles");
city.put("state", "CA");
city.put("country", "USA");
db.collection("cities").document("LA")
.set(city)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully written!");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
This is my security rule
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
allow create: if (request.auth.uid != null);
allow update: if (request.auth.uid != null) && !("country" in request.writeFields) );
}
}
}
As you see from security rules, update can happen only when the document does not contain "country" field. Create rule is straightforward.
In this example, I do not have the document "LA" in the collection and when I test it, I get PERMISSION DENIED error. Tweaking the update rule confirms, .set() is calling update rule.
How do I make .set call "create" rule exclusively?