checking for record access in visual workflow
the UserRecordAccess object “Represents a user’s access to a set of records”.
in apex, you can query this object to determine if a user can view, edit, delete, share, or transfer a record.
SELECT RecordId, HasReadAccess, HasTransferAccess, MaxAccessLevel
FROM UserRecordAccess
WHERE UserId = [single ID]
AND RecordId = [single ID]
in flow, you can query this object to test for edit before updates, in theory, but its got some quirks because it has very specific requirements around how the query is structured, and the standard flow “get records” element does not meet them.
the docs specify these requirements for the query. the 2nd and 3rd ones come into play here.
SOQL restrictions:
- When the running user is querying a user’s access to a set of records, records that the running user does not have read access to are filtered out of the results.
- When filtering by UserId and RecordId only, you must use SELECT RecordId and optionally one or more of the access level fields:HasReadAccess, HasEditAccess, HasDeleteAccess, HasTransferAccess, and HasAllAccess. You may include MaxAccessLevel.
- When filtering by UserId, RecordId, and an access level field, you must use SELECT RecordId only.
if you do a regular ‘get records’, filter on userId and recordId, and store all fields, you will likely get this error
Error Occurred: This error occurred when the flow tried to look up records: RecordId field must be selected.
This is because you must include the recordId field in the select clause from the query, and the ‘store all fields’ option does not specify that field unless you reference it later. (note that referenceing recordId downstream in the flow also does not work, for reasons i will get to next).
The query, roughly, is being run as:
SELECT HasEditAccess FROM UserRecordAccess WHERE RecordId = [filterValue] AND UserId = [filterValue]
and it needs to be
SELECT RecordId, HasEditAccess FROM UserRecordAccess WHERE RecordId = [filterValue] AND UserId = [filterValue]
So, I modified the get records to use the option where you can specify the fields to store, and stored RecordId and HasEditAccess. And then got this new errror
Error Occurred: This error occurred when the flow tried to look up records: Can select only RecordId, a Has*Access field, and MaxAccessLevel.
This is because flow always includes the Id field, and apparently returning the Id field of the userRecordAccess record is not acceptable.
This same error is also thrown if you try to reference the recordId field downstream (say in a decision) to get flow to include it the query, presumably because the Id field is still included.
So i went the manually assign variables route, and it was successful.
note that you must store recordId in a variable to get this to work, even though you are also passing it in as a filter value, else you will get the 1st error.
note you also can use the new-ish IN parameter to get a bunch of records : //or Record IN [list of IDs]