I'm trying to setup a role-based Firestore security rules but I'm stuck with how to create a new document if the incoming data uid matches with the auth uid.
But where to define that incoming uid?
I have tried to initialize the user uid of the new user to my model like this code below but it still missing some permissions.
final personalInfoData = PersonalInfoModel(
uid: auth.getUid(),
name: name,
age: int.parse(age),
);
Here is my code looks like
match /profile/{profileId}/{document=**}{
allow read: if isSignedIn() && docIdEqualsAuthId(profileId);
allow create: if isSignedIn() && incomingUidEqualsAuthId();
}
function isSignedIn(){
return request.auth != null;
}
function docIdEqualsAuthId(profileId){
return profileId == request.auth.uid;
}
function incomingUidEqualsAuthId(){
return request.resource.data.uid == request.auth.uid;
}
Here is my controller code :
String getUid() {
return auth.currentUser!.uid;
}
final personalInfoData = PersonalInfoModel(
name: name,
age: int.parse(age),
);
DocumentReference profileCRef =
firestore.collection("profile").doc(auth.getUid());
try {
await profileCRef.set({'personalInfo': json}, SetOptions(merge: true));
} on Exception catch (e) {
print(e);
}
The way I setup my controller is it will create a new document with a document Id of request.auth.uid
of the new user.
I want rules to identify if the new user is authenticated and the incoming request to create a profile info must have a valid user id that matches with the auth uid.
If the document still not exists in the database then create a new document with an ID of the uid.
The error I'm getting is this
W/Firestore(14626): (24.0.1) [WriteStream]: (221034) Stream closed with status: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}.
W/Firestore(14626): (24.0.1) [Firestore]: Write failed at profile/N8CuobvPdHXr40KYgebw52SmOBp2: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
CodePudding user response:
The request.resource.data
is the data that you are trying to add in the document. Currently uid
is not a field in document but a property in personalInfo
map. So you must specify path to the field that you are trying to read in security rules. The following should work:
function incomingUidEqualsAuthId(){
return request.resource.data.personalInfo.uid == request.auth.uid;
}