Loading

How to Retrieve All Public Groups for a Salesforce User Using Apex (Direct, Role-Based, and Nested Groups)

Fecha de publicación: Jun 9, 2026
Descripción

Overview

In Salesforce, a user can belong to Public Groups in three different ways:

  1. Direct Groups — The user is a direct member of the group via a GroupMember record.
  2. Role-Based Groups — The group contains the user's Role as a member. If a Group has a Role as its RelatedId, any user with that Role is implicitly a member of the group.
  3. Nested Groups — A group contains another group as a member. If a user belongs to Group A, and Group A is a member of Group B, the user is also an indirect member of Group B.

This article explains how to retrieve all three types of Public Group membership for a specific Salesforce user programmatically using Apex code.

Solución

How the Apex Code Works

The following approach retrieves all Public Group IDs that a given user belongs to, covering direct, role-based, and nested group membership:
Step 1 — Build a map of Role-Based Groups. Query all Group records and build a Map where the key is the RelatedId field (which stores the User Role ID for role-based groups) and the value is the Group ID. This allows quick lookup of whether a user's role belongs to any group.
Step 2 — Find Direct Group memberships. Query the GroupMember object for all records where the UserOrGroupId field matches the target User ID, filtering for Group Types of Regular, Role, and RoleAndSubordinates. Add the GroupId from each result to a Set of direct group IDs.
Step 3 — Find Role-Based Group memberships. Query the User object for the target user's UserRoleId. Check whether that UserRoleId exists as a key in the map built in Step 1. If it does, add the corresponding Group ID to the results Set.
Step 4 — Combine direct and role-based results. Merge the direct group Set and the role-based results into a single results Set.
Step 5 — Find Nested Group memberships. Query all GroupMember records where the Group Type is Regular, Role, or RoleAndSubordinates, and build a second Map of UserOrGroupId to GroupId. Iterate through the current results Set and check whether any of those Group IDs appear as a UserOrGroupId in the nested groups Map. If so, add the parent Group ID to the results Set. This covers groups that contain other groups as members.
Step 6 — Output the results. Use System.debug() to print the final Set of Group IDs, which contains all Public Groups — direct, role-based, and nested — that the user belongs to.
Important: Replace the placeholder User ID in the code with the actual 15 or 18-character Salesforce User ID of the user you want to check. The code provided is an example — review and modify it for your specific organization before executing.

 The below sample code would work as it covers all requirements:
 

//Declaring a Set as we don't want Duplicate Group Ids
Set<Id> results = new Set<Id>();

///Declaring a Map for Group with Role
Map<Id,Id> grRoleMap = new Map<Id,Id>();

//Populating the Map with RelatedID(i.e.UserRoledId) as Key
for(Group gr : [select id,relatedid,name from Group])
{
	grRoleMap.put(gr.relatedId,gr.id);
}

//Groups directly associated to user
Set<Id> groupwithUser = new Set<Id>();

//Populating the Group with User with GroupId we are filtering only  for Group of Type Regular,Role and RoleAndSubordinates
for(GroupMember  u :[select groupId from GroupMember where UserOrGroupId='<User Id>' and (Group.Type = 'Regular' OR Group.Type='Role' OR Group.Type='RoleAndSubordinates')])
{
	groupwithUser.add(u.groupId);
}

//Groups with Role
for(User  u :[select UserRoleId from User where id='<User Id>'])
{
	//Checking if the current User Role is part of Map or not
	if(grRoleMap.containsKey(u.UserRoleId))
	{
		results.add(grRoleMap.get(u.UserRoleId));
	}
}
//Combining both the Set
results.addAll(groupwithUser);

//Traversing the whole list of Groups to check any other nested Group
Map<Id,Id> grMap = new Map<Id,Id>();
for(GroupMember gr : [select id,UserOrGroupId,Groupid from GroupMember where
        (Group.Type = 'Regular' OR Group.Type='Role' OR Group.Type='RoleAndSubordinates')])
{
	grMap.put(gr.UserOrGroupId,gr.Groupid);
}
for(Id i :results)
{
	if(grMap.containsKey(i))
	{
		results.add(grMap.get(i));
	}
}

system.debug('########' + results);


NOTE: The code provided is an example. Please review and make modifications for your organization.
 

Número del artículo de conocimiento

000387341

 
Cargando
Salesforce Help | Article