I'm new to coding and I'm practicing by creating a trigger that will update the Contact Owner depending on the Email field value.

For example, I have the Email field value is [email protected] then it will try to look for User that has [email protected] email then it will update the Contact Owner.

This is what I've done so far:

trigger AutoChangeOwner on Contact (before insert, before update) {

    Set<String> conEmail = new set<String>();
    Map<String, Id> UsrMap = new map<String, Id>();

    for(Contact con : trigger.new ){
        system.debug('conemail' + conEmail);

    List<User> userEmail = [SELECT Id, Name, Email FROM User WHERE Email != null];
    for(User u : userEmail){
            UsrMap.put(u.Email, u.Id); 
            system.debug('useremail' + userEmail);

    for(Contact c : trigger.new){
        c.Text__c = UsrMap.get(c.Email);


The code is compiling without any error but the Owner field is not getting updated when I change any field in contact. Any ideas?

Any kind of explanation, code snippet, best approach to achieve my goal is much appreciated!

1 Answer 1


You are on the right track with a well-bulkified trigger; this is a good start. The error

Illegal assignment from Set to Id

comes from this line:

        c.OwnerId = UsrId;

OwnerId is a single Id field; UsrId is declared as a Set<Id>.

The chief problem you seem to have here is mapping between email addresses and user Ids. What you need is a Map here:

for(User u : userEmail){

These Lists don't do you any good. Instead, create a new variable typed as a Map<String, Id>. As you loop through User records, add each to the map:

myMap.put(u.Email, u.Id);

(Note for later that you don't have a solution here if more than one User has the same Id).

Then, when you loop over Contacts,

    if(conEmail == UserList){
        c.OwnerId = UsrId;

You don't want to do this, because you're comparing the whole sets conEmail and UserList, and what you're interested in is this Contact, c. But if you have the Map described above in hand, you can use the user's email address to look up in that Map what its new OwnerId should be:

if (myMap.containsKey(c.Email)) {
    c.OwnerId = myMap.get(c.Email);

Using a Map also ensures that your code doesn't run slowly by iterating needlessly over records that do not match because Map lookups are constant-time: the time required to check the value corresponding to some key is constant, and doesn't grow with size.

  • Thank you so much @David this will add up to my knowledge. I've updated the code and I'm having errors. What's the possible cause of the error? Oct 29, 2019 at 0:30
  • @Naofumi it's containsKey, sorry. My mistake!
    – David Reed
    Oct 29, 2019 at 0:34
  • Thanks again @David the code is compiling without any error but the Owner field is not getting updated when I change any field in contact. Any ideas? Oct 29, 2019 at 0:48
  • is my query correct? I think the reason why it's not updating is because it fails to get the User that has the same Email conEmail Oct 29, 2019 at 1:22
  • @NaofumiKun did you figure this out? It might be helpful to run some queries in Developer Console or add logging.
    – David Reed
    Oct 29, 2019 at 15:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .