function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Bindhyachal Kumar SinghBindhyachal Kumar Singh 

How to get all Users of a Public Group?

I want get a list of all the users who are part of public group of the currently logged in user. In documentations, i have read that  able to pick these values from group and group member objects.

A record exists for every User or Group who is a direct member of a public group whose Type field is set to Regular. User records that are indirect members of Regular public groups are not listed as group members. A User can be an indirect member of a group if he or she is in a UserRole above the direct group member in the hierarchy, or if he or she is a member of a group that is included as a subgroup in that group.

Can we get all users of a group using group id? Please help me ASAP it's urgent.
Best Answer chosen by Bindhyachal Kumar Singh
Bindhyachal Kumar SinghBindhyachal Kumar Singh
I have done this and able to get all users for a public group including Roles. Use following running code.

public static Map<id,integer> limitMap(){
        List<EntitySubscription> eList = new List<EntitySubscription>();
        eList = [select id,ParentId,SubscriberId from EntitySubscription where SubscriberId IN: activeusersMap.keyset() limit 40000];
        Map<id,integer> count = new Map<id,integer>();
        for(EntitySubscription e : eList){
            if(count.get(e.SubscriberId)==null)
                count.put(e.SubscriberId,1);
            else{
               integer c = count.get(e.SubscriberId);
               c=c+1;
               count.put(e.SubscriberId,c);
            }
        }
        return count;
    }
   
    public static Set<ID> getAllSubRoleIds(Set<ID> roleIds) {

    Set<ID> currentRoleIds = new Set<ID>();

    // get all of the roles underneath the passed roles
    for(UserRole userRole :[select Id from UserRole where ParentRoleId
      IN :roleIds AND ParentRoleID != null limit 40000])
    currentRoleIds.add(userRole.Id);

    // go fetch some more rolls!
    if(currentRoleIds.size() > 0)
      currentRoleIds.addAll(getAllSubRoleIds(currentRoleIds));

    return currentRoleIds;

  }
   
    public static set<id> GetUserIdsFromGroups(set<id> groupids){
        Set<Id> result=new Set<Id>();
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        String roleType = Schema.SObjectType.UserRole.getKeyPrefix();
        Set<Id> groupIdProxys = new Set<Id>();
        // Loop through all group members in a group
        Set <Id> groupWithRole = new Set<Id>();
        set<Id> groupWithRoleNSub = new set<Id>();
        id firstelement = null;
        //Create map if group
       
        //where Id IN : groupIds
 
        for(Id i: groupids){
            firstelement = i;
            break;
        }

        if(String.valueOf(firstelement.getSObjectType()) == 'Group'){
            for(GroupMember m : [Select Id, UserOrGroupId,GroupId,Group.type From GroupMember Where GroupId in :groupIds]) {
                System.debug('ttttt :' +m);
                // If the user or group id is a user
                if(((String)m.UserOrGroupId).startsWith(userType) && activeusersMap.get(m.UserOrGroupId) != null)
                {
                    result.add(m.UserOrGroupId);
                }
                else if(grMap.get(m.UserOrGroupId) !=null && ( grMap.get(m.UserOrGroupId).relatedid !=null && ((String)grMap.get(m.UserOrGroupId).relatedid).startsWith(roleType) )){
                   // system.debug('type is::::'+grMap.get(m.UserOrGroupId).type); 
                   
                    if(grMap.get(m.UserOrGroupId).type == 'Role')    
                        groupWithRole.add(grMap.get(m.UserOrGroupId).relatedid);
                    else if(grMap.get(m.UserOrGroupId).type == 'RoleAndSubordinatesInternal') 
                        groupWithRoleNSub.add(grMap.get(m.UserOrGroupId).relatedid);     
                }
                // If the user or group id is a group
                // Note: there may be a problem with governor limits if this is called too many times
                else if (((String)m.UserOrGroupId).startsWith(groupType)) {                   
                    // Call this function again but pass in the group found within this group
                    groupIdProxys.add(m.UserOrGroupId);
                }
            }
            //system.debug('groupwithrole::::'+groupWithRole);
            if(groupWithRoleNSub.size() > 0){
                groupWithRoleNSub.addALL(getAllSubRoleIds(groupWithRoleNSub));
                Map<Id,User> users = new Map<Id, User>([Select Id, Name From User where UserRoleId IN :groupWithRoleNSub AND isActive =: true]);
                result.addALL(users.keyset());   
            }
            else if(groupWithRole.size()>0){
                Map<Id,User> users = new Map<Id, User>([Select Id, Name From User where UserRoleId IN :groupWithRole AND isActive =: true]);
                result.addALL(users.keyset());
            }
           
            if(groupIdProxys.size() > 0)
            {
                result.addAll(GetUserIdsFromGroups(groupIdProxys));
            }
        }else if(String.valueOf(firstelement.getSObjectType()) == 'CollaborationGroup'){
            for (CollaborationGroupMember m : [select  id, CollaborationGroupId,MemberId from CollaborationGroupMember
                                               where CollaborationGroupId IN :groupIds]){
                System.debug('MMM'+m.MemberId);
                // If the user or group id is a user
                if (((String)m.MemberId).startsWith(userType) && activeusersMap.get(m.MemberId) != null){
                    result.add(m.MemberId);
                }             
            }
        }
        System.debug('RRRRRRRR: '+result);
        return result; 
    }

All Answers

Vinit_KumarVinit_Kumar
We can query on GroupMember object something like below :-

SELECT UserOrGroupId FROM GroupMember WHERE GroupId = <Some group id>

and then we can check key prefix if the key prefix is '005',then it is a user and add that user to list or if the key preifx is '00G' this is a group,then we can query users based upon this group and again that to the list of users.

Hope this helps!!
Bindhyachal Kumar SinghBindhyachal Kumar Singh
Hi Vinit ,

You are right but when a group have a Role and Internal Subordoniates then it is not fetching users thru groupmember Soql.

Letus say if memebr has keyprefix - 00G then what will be query for this?

If we use same SELECT UserOrGroupId FROM GroupMember WHERE GroupId = <Some group id> then it does not return any result and we get only direct member not all users.
Vinit_KumarVinit_Kumar
Hi Bindhayachal,

This is what I did ,

List<GroupMember> gm = [SELECT UserOrGroupId FROM GroupMember WHERE GroupId = '00GZ00000014mLy'];
List<GroupMember> gm1 = new List<GroupMember>();

List<String> strList = new List<String>();

for(GroupMember g : gm)
{
      strList.add(g.UserOrGroupId);
}

for(String s : strList)
{
    if(s.contains('00G'))
    {

      gm1 = [SELECT UserOrGroupId FROM GroupMember WHERE GroupId =: s];
system.debug('@@@@@@@@@' + gm1);
    }
}

and you need to continue this process unless u don't have any Group left as UserOrGroupId.
Bindhyachal Kumar SinghBindhyachal Kumar Singh
Hi Vinit,

It only returns memebr whose type is user. Also gm1 does not return any result for Role and subordinates (only for public groups).
khillan bhardwajkhillan bhardwaj
Hi Vinit Kumar,

I have did same allready. but we are not able to fetch user by 'Role' or  'Role Internal Subordinate'...etc. we are able to retrieve those user which are search by user and public group. but we are not able to fetch userid of those user which are added by role or 'Role Internal Subordinate' ..etc.we made code like follow : 

public static Set<id> GetUserIdsFromGroup(Set<Id> groupIds){
        // store the results in a set so we don't get duplicates
        Set<Id> result=new Set<Id>();
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        Set<Id> groupIdProxys = new Set<Id>();
        // Loop through all group members in a group
       
        for(GroupMember m : [Select Id, UserOrGroupId From GroupMember Where GroupId in :groupIds]) {
            system.debug('UserOrGroupId======='+m.UserOrGroupId+'------------'+groupType );
            // If the user or group id is a user
            if(((String)m.UserOrGroupId).startsWith(userType))
            {
                result.add(m.UserOrGroupId);
            }
            // If the user or group id is a group
            // Note: there may be a problem with governor limits if this is called too many times
            else if (((String)m.UserOrGroupId).startsWith(groupType))
            {
               
                // Call this function again but pass in the group found within this group
                groupIdProxys.add(m.UserOrGroupId);
            }
        }
        if(groupIdProxys.size() > 0)
        {
            result.addAll(GetUSerIdsFromGroup(groupIdProxys));
        }
        return result; 
    }

In the method parameter we pass set of one group id .

Thanks 
Khillan Singh
Patrick WatkinsPatrick Watkins
Did anybody ever figure this out?  Would really like to know if there's a way to fetch the members of a group that is of type Role or Role and Subordinates.  There's so many use cases where that would be useful.
Mitesh SuraMitesh Sura
There is NO way to get Users from a Role , if that Role is GroupMember. Here is the issue. UserOrGroupId from GroupMember does not spit RoleId, like it does UserId.

UserOrGroupId will either be
- 005xxxx --> This is actual user, which is correct. 
- 00Gxxxx --> This is a Role id which is NOT correct. If you look in the UI, RoleId starts from OOE. There is no co-relation between OOG and OOE. I tried "Group_RelatedId" child relationship under UserRole, that does not help either. 

Any pointers? 
Bindhyachal Kumar SinghBindhyachal Kumar Singh
I have done this and able to get all users for a public group including Roles. Use following running code.

public static Map<id,integer> limitMap(){
        List<EntitySubscription> eList = new List<EntitySubscription>();
        eList = [select id,ParentId,SubscriberId from EntitySubscription where SubscriberId IN: activeusersMap.keyset() limit 40000];
        Map<id,integer> count = new Map<id,integer>();
        for(EntitySubscription e : eList){
            if(count.get(e.SubscriberId)==null)
                count.put(e.SubscriberId,1);
            else{
               integer c = count.get(e.SubscriberId);
               c=c+1;
               count.put(e.SubscriberId,c);
            }
        }
        return count;
    }
   
    public static Set<ID> getAllSubRoleIds(Set<ID> roleIds) {

    Set<ID> currentRoleIds = new Set<ID>();

    // get all of the roles underneath the passed roles
    for(UserRole userRole :[select Id from UserRole where ParentRoleId
      IN :roleIds AND ParentRoleID != null limit 40000])
    currentRoleIds.add(userRole.Id);

    // go fetch some more rolls!
    if(currentRoleIds.size() > 0)
      currentRoleIds.addAll(getAllSubRoleIds(currentRoleIds));

    return currentRoleIds;

  }
   
    public static set<id> GetUserIdsFromGroups(set<id> groupids){
        Set<Id> result=new Set<Id>();
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        String roleType = Schema.SObjectType.UserRole.getKeyPrefix();
        Set<Id> groupIdProxys = new Set<Id>();
        // Loop through all group members in a group
        Set <Id> groupWithRole = new Set<Id>();
        set<Id> groupWithRoleNSub = new set<Id>();
        id firstelement = null;
        //Create map if group
       
        //where Id IN : groupIds
 
        for(Id i: groupids){
            firstelement = i;
            break;
        }

        if(String.valueOf(firstelement.getSObjectType()) == 'Group'){
            for(GroupMember m : [Select Id, UserOrGroupId,GroupId,Group.type From GroupMember Where GroupId in :groupIds]) {
                System.debug('ttttt :' +m);
                // If the user or group id is a user
                if(((String)m.UserOrGroupId).startsWith(userType) && activeusersMap.get(m.UserOrGroupId) != null)
                {
                    result.add(m.UserOrGroupId);
                }
                else if(grMap.get(m.UserOrGroupId) !=null && ( grMap.get(m.UserOrGroupId).relatedid !=null && ((String)grMap.get(m.UserOrGroupId).relatedid).startsWith(roleType) )){
                   // system.debug('type is::::'+grMap.get(m.UserOrGroupId).type); 
                   
                    if(grMap.get(m.UserOrGroupId).type == 'Role')    
                        groupWithRole.add(grMap.get(m.UserOrGroupId).relatedid);
                    else if(grMap.get(m.UserOrGroupId).type == 'RoleAndSubordinatesInternal') 
                        groupWithRoleNSub.add(grMap.get(m.UserOrGroupId).relatedid);     
                }
                // If the user or group id is a group
                // Note: there may be a problem with governor limits if this is called too many times
                else if (((String)m.UserOrGroupId).startsWith(groupType)) {                   
                    // Call this function again but pass in the group found within this group
                    groupIdProxys.add(m.UserOrGroupId);
                }
            }
            //system.debug('groupwithrole::::'+groupWithRole);
            if(groupWithRoleNSub.size() > 0){
                groupWithRoleNSub.addALL(getAllSubRoleIds(groupWithRoleNSub));
                Map<Id,User> users = new Map<Id, User>([Select Id, Name From User where UserRoleId IN :groupWithRoleNSub AND isActive =: true]);
                result.addALL(users.keyset());   
            }
            else if(groupWithRole.size()>0){
                Map<Id,User> users = new Map<Id, User>([Select Id, Name From User where UserRoleId IN :groupWithRole AND isActive =: true]);
                result.addALL(users.keyset());
            }
           
            if(groupIdProxys.size() > 0)
            {
                result.addAll(GetUserIdsFromGroups(groupIdProxys));
            }
        }else if(String.valueOf(firstelement.getSObjectType()) == 'CollaborationGroup'){
            for (CollaborationGroupMember m : [select  id, CollaborationGroupId,MemberId from CollaborationGroupMember
                                               where CollaborationGroupId IN :groupIds]){
                System.debug('MMM'+m.MemberId);
                // If the user or group id is a user
                if (((String)m.MemberId).startsWith(userType) && activeusersMap.get(m.MemberId) != null){
                    result.add(m.MemberId);
                }             
            }
        }
        System.debug('RRRRRRRR: '+result);
        return result; 
    }
This was selected as the best answer
Saurabh OberoiSaurabh Oberoi
1. Get the UserOrGroupId for the Queue starting with 00G:

SELECT Group.Id, Group.Name, UserOrGroupId FROM GroupMember where Group.type='Queue'


2. Get the related role Id starting with 00E:

SELECT Id, Name, Type, RelatedId FROM Group where Id = '00Gxxxxxxxxxxxxxxx'

here 00Gxxxxxxxxxxxxxxx is the UserOrGroupId for the role assigned to your queue


3. Use the related Id obtained in previous step to get the users:

Select Id, Name from User where UserRoleId = '00E11000000LXACEA4'
Naveen ChughNaveen Chugh
a far more easier code for this issue is as follows:

public static Set<id> GetUserIdsFromGroup(Set<Id> groupIds)
    {
        // store the results in a set so we don't get duplicates
        Set<Id> result=new Set<Id>();
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        Set<Id> groupIdProxys = new Set<Id>();
        // Loop through all group members in a group
        for(GroupMember m : [Select Id, UserOrGroupId, Group.Type, Group.RelatedId From GroupMember Where GroupId in :groupIds])
        {
            // If the user or group id is a user
            if(((String)m.UserOrGroupId).startsWith(userType))
            {
                result.add(m.UserOrGroupId);
            }
            // If the user or group id is a group
            // Note: there may be a problem with governor limits if this is called too many times
            else if (((String)m.UserOrGroupId).startsWith(groupType))
            {
                // Call this function again but pass in the group found within this group
                groupIdProxys.add(m.userOrGroupId);
                
            }
        }
        if(groupIdProxys.size() > 0)
        {    
            Set<id> groupId = new set<id>();
            Set<id> roleId = new set<id>();
            Set<id> roleAndSubId = new set<Id>();

            for(Group g2 : [Select Id, Type, relatedId From Group Where Id = :groupIdProxys]){
                if(g2.Type == 'Role'){
                    roleId.add(g2.relatedId);    
                }
                else if(g2.Type== 'RoleAndSubordinates'){
                    roleAndSubId.add(g2.relatedId);    
                }
                else if(g2.Type== 'PRMOrganization'){
                    roleId.add(g2.relatedId);    
                }
                else if(g2.Type== 'Regular'){
                    groupId.add(g2.id);    
                }
                system.debug(g2);
            }
            if(roleAndSubId.size()>0){
                roleId.addAll(getAllSubRoleIds(roleAndSubId));
            }
            if(roleId.size()>0){
                for(User u: [select id from user where UserRoleId IN: roleId]){
                    result.add(u.id);
                }
            }
            if(groupId.size()>0){
                for(GroupMember gm : [select id, UserOrGroupId from GroupMember where GroupId IN: groupId]){
                    result.add(gm.UserOrGroupId);        
                }
            }
        }
        return result;  
    }
    
    public static Set<ID> getAllSubRoleIds(Set<ID> roleIds) {
    
        Set<ID> currentRoleIds = new Set<ID>();
    
        // get all of the roles underneath the passed roles
        for(UserRole userRole :[select Id from UserRole where ParentRoleId IN :roleIds AND ParentRoleID != null limit 40000])
            currentRoleIds.add(userRole.Id);
    
        // go fetch some more rolls!
        if(currentRoleIds.size() > 0)
          currentRoleIds.addAll(getAllSubRoleIds(currentRoleIds));
    
        return currentRoleIds;
    
    }
CHAYAN BATABYALCHAYAN BATABYAL
The below code gets user id of all the users inside any specific public group.(Right now only inner public groups (and their users along with public groups) are taken into account).



Pass any specific group Id to the getAllPublicGroupUsers method below:

public class XYZ{
    public Map<id, Set<Id>> mapOfGroupIdToUsersOnly = new Map<id, Set<Id>>();
    public Map<id, Set<Id>> mapOfGroupIdToInnerGroups = new Map<id, Set<Id>>();
    public Set<Id> userIdSet = new Set<Id>();
    
    public XYZ(){
        createMapsOfGroups();
    }
    
    public Set<Id> getAllPublicGroupUsers(Id GroupId){
        if(mapOfGroupIdToUsersOnly != NULL && mapOfGroupIdToUsersOnly.containsKey(GroupId))
            userIdSet.addAll(mapOfGroupIdToUsersOnly.get(GroupId));
        
        if(mapOfGroupIdToInnerGroups.containsKey(GroupId)){
            for(Id eachInnerGroup : mapOfGroupIdToInnerGroups.get(GroupId)){
                getAllPublicGroupUsers(eachInnerGroup);
            }
        }
        
        return userIdSet;
    }

    public void createMapsOfGroups(){
        for(GroupMember eachGroupMember : [SELECT UserOrGroupId, GroupId, Group.Name FROM GroupMember where Group.Type = 'Regular'])
        {
            if(String.valueOf(eachGroupMember.UserOrGroupId).startsWith('005'))
            {
                if(!mapOfGroupIdToUsersOnly.containsKey(eachGroupMember.GroupId))
                    mapOfGroupIdToUsersOnly.put(eachGroupMember.GroupId, new Set<Id>());
                
                mapOfGroupIdToUsersOnly.get(eachGroupMember.GroupId).add(eachGroupMember.UserOrGroupId);
            }
            
            else if(String.valueOf(eachGroupMember.UserOrGroupId).startsWith('00G'))
            {
                if(!mapOfGroupIdToInnerGroups.containsKey(eachGroupMember.GroupId))
                    mapOfGroupIdToInnerGroups.put(eachGroupMember.GroupId, new Set<Id>());
                
                mapOfGroupIdToInnerGroups.get(eachGroupMember.GroupId).add(eachGroupMember.UserOrGroupId);
            }
        }
    }
}
Parmanand SheteParmanand Shete

Please refer to below code

 

public static Set<Id> recursiveGetUserIds(set<Id> userOrGroupIds){
        set<Id> userIds = new set<Id>();
        set<Id> groupIds = new set<Id>();
        List<GroupMember> groupMemberList = [Select UserOrGroupId From GroupMember where GroupId IN:userOrGroupIds];
        for(GroupMember gm : groupMemberList){
            string userOrGroupId = gm.UserOrGroupId;
            string init = userOrGroupId.substring(0,3);
            if(init == '005'){
                userIds.add(gm.UserOrGroupId);
            }else{
                groupIds.add(gm.UserOrGroupId);
            }
        }
        if(groupIds.size()>0){
            Set<id> groupId = new set<id>();
            Set<id> roleId = new set<id>();
            Set<id> roleAndSubId = new set<Id>();
            
            for(Group gp : [Select Id, Type, relatedId From Group Where Id =:groupIds]){
                if(gp.Type == 'Role'){
                    roleId.add(gp.relatedId);    
                }
                else if(gp.Type== 'RoleAndSubordinates'){
                    roleAndSubId.add(gp.relatedId);    
                }
                else if(gp.Type== 'PRMOrganization'){
                    roleId.add(gp.relatedId);    
                }
                else if(gp.Type== 'Regular'){
                    groupId.add(gp.id);    
                }
            }
            if(roleAndSubId.size()>0){
                roleId.addAll(getAllSubRoleIds(roleAndSubId));
            }
            if(roleId.size()>0){
                List<user> userList= [select id from user where UserRoleId IN:roleId];
                for(User u: userList){
                    userIds.add(u.id);
                }
            }
            if(groupId.size()>0){
                userIds.addAll(recursiveGetUserIds(groupId));
            }
        }
        return userIds;
    }
    public static Set<ID> getAllSubRoleIds(Set<ID> roleIds) {
        Set<ID> currentRoleIds = new Set<ID>();
        for(UserRole userRole :[select Id from UserRole where ParentRoleId IN :roleIds]){
            currentRoleIds.add(userRole.Id);
        }
        if(currentRoleIds.size() > 0){
            currentRoleIds.addAll(getAllSubRoleIds(currentRoleIds));
        }
        return currentRoleIds;
    }