0

Using this as a reference:

https://developer.salesforce.com/page/Synchronizing_Portal_Users_with_Contact_Record_Data

I am trying to sync the date in the LastLoginDate field on the user object with a custom field on the contact object. We have community portal users and would like to be able to compare the contact record with other internal objects, without using administrative reports to get login data.

So far, I can make it work using the examples above to sync the fields between user & contact when an actual update is saved, like changing title or suffix. However, just logging in does not seem to trigger any record updates. Not sure how I can automate this so that if someone logs in, it updates the login time on the contact record.

Class:

global class UpdateContactPortalUser {
@future
public static void updateContacts(string userId)
{
    User u = [select Id,ContactId,LastLoginDate from User where id = :userId];

    if (u != null && u.ContactId != null)
    {
        Contact c = new Contact (id = u.ContactId, ContactLogin__c = u.LastLoginDate);
        update c;
    }
} }

Trigger:

trigger UpdateContactFromPortalUser on User (after update) {
if (Trigger.new.size()==1)
{
    User u = Trigger.new[0];
    if (u.ContactId != null)
    {
        UpdateContactPortalUser.updateContacts(u.Id);
    }
} }

Any help is much appreciated. I have also thought of using batch apex to copy LastLoginDate into a custom date field on the user object and going from there, but seem to be running into the same issue.

Edit: On the advice of sdfcfox, I'm now investigating doing this in a scheduled class via batch apex, but not getting any luck with records updating at all. Kind of stumped on how to create a method to actually do this.

Here's the class and I'm narrowing the list of users to only ones with certain profiles (portals):

global class CaptureLog implements Database.Batchable<sObject>{
public string sQuery;
public string ProfID = '00e36000001dXAy';

global Database.Querylocator start (Database.BatchableContext BC)
{
    sQuery = 'SELECT Id, contactid,LastLoginDate FROM User WHERE ProfileId = \''+ProfID+'\'';
    system.debug(sQuery);
    return Database.getQueryLocator(sQuery);
}

global void execute(Database.BatchableContext BC, List<User> scope)

{
    List<Contact> contacts = new List<Contact>();
    for(User u : scope)
    {
        contacts.add(new Contact(ContactLogin__c = u.LastLoginDate));
    }

}

global void finish(Database.BatchableContext BC)
{

}}
3
  • 1
    I'm pretty sure a login event doesn't trigger triggers, only actual updates to the record. You'll probably want to write a scheduled class that kicks off periodically to check for new logins. – sfdcfox Mar 5 '18 at 21:05
  • So basically a scheduled class that will check to see if anyone has logged in recently, and if they have, update the custom field on the contact? Or am I using that to kick off the trigger that already does that? – bblackinton Mar 5 '18 at 21:13
  • I'd skip the trigger, it's really a waste of time. Just update the records that need updating. – sfdcfox Mar 5 '18 at 21:16
0

I had the exact same problem and I found the solution as a scheduled apex batch class only.

Batch Class

global class BatchLoginData implements Database.Batchable<sObject>{
    public string sQuery;
    public string ProfID = '00e5w000000k5JMAAY';
    global Database.Querylocator start (Database.BatchableContext BC){
        sQuery = 'SELECT Id, contactid,LastLoginDate FROM User WHERE ProfileId = 
        \''+ProfID+'\'';
        return Database.getQueryLocator(sQuery);
    }
    global void execute(Database.BatchableContext BC, List<User> newUsers){
        List<Contact> cons=new List<Contact>();
        for(User u:newUsers){
            if(u.LastLoginDate!=null){
                User user=[select ContactId,LastLoginDate from user where id=:u.id];
                Contact con=[select id,Last_Login_DT__c from Contact where 
                id=:user.ContactId];
                con.Last_Login_DT__c=user.LastLoginDate;
                cons.add(con);
            }
        }
        update cons;
    }

    global void finish(Database.BatchableContext BC){
    }
}

BatchSchedule Class

global class BatchLoginDataSchedule implements Schedulable{
    global void execute(SchedulableContext sc) {
        Database.executeBatch(new BatchLoginData());
    }
}

And run this in anonymous block to run it and it will get updated every hour

BatchLoginDataSchedule sc = new BatchLoginDataSchedule();
String cronExp = '0 0 * * * ?';
String jobID = System.schedule('Update Contact', cronExp, sc);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.