title: Update user data after login in Symfony 3
body: <p>I am getting in touch with Symfony, this is my first app and I am trying to understand all the environment. This is a very simple question but after a long surf by the web I didn't get how to do it.</p>
  
  <p>I have a login form working very nice with a listener to handle success or error, all works nice but the problem comes when I try to update the last access date for the user.</p>
  
  <p>I have an user entity (taken from the docs):</p>
  
  <pre><code>&lt;?php
  namespace AppBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Security\Core\User\AdvancedUserInterface;
  
  /**
   * @ORM\Table(name="app_users")
   * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
   */
  class User implements AdvancedUserInterface, \Serializable
  {
      /**
       * @ORM\Column(type="integer")
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      private $id;
  
      /**
       * @ORM\Column(type="string", length=25, unique=true)
       */
      private $username;
  
      /**
       * @ORM\Column(type="string", length=64)
       */
      private $password;
  
      /**
       * @ORM\Column(type="string", length=60, unique=true)
       */
      private $email;
  
      /**
       * @ORM\Column(name="is_active", type="boolean")
       */
      private $isActive;
  
      /**
       * @ORM\Column(name="salt", type="string", length=100)
       */
      private $salt;
  
      /**
       * @ORM\Column(type="datetime", nullable=true)
       */
      private $lastLogin = null;
  
      /**
       * @ORM\Column(type="datetime", nullable=true)
       */
      private $createdAt = null;
  
      public function __construct()
      {
          $this-&gt;isActive = true;
          // may not be needed, see section on salt below
          // $this-&gt;salt = md5(uniqid(null, true));
      }
  
      public function getUsername()
      {
          return $this-&gt;username;
      }
  
      public function setSalt($salt)
      {
          $this-&gt;salt = $salt;
      }
  
      public function getSalt()
      {
          // you *may* need a real salt depending on your encoder
          // see section on salt below
          return null;
      }
  
      public function getPassword()
      {
          return $this-&gt;password;
      }
  
      public function getRoles()
      {
          return array('ROLE_USER');
      }
  
      public function eraseCredentials()
      {
      }
  
      public function isAccountNonExpired()
       {
           return true;
       }
  
       public function isAccountNonLocked()
       {
           return true;
       }
  
       public function isCredentialsNonExpired()
       {
           return true;
       }
  
       public function isEnabled()
       {
           return $this-&gt;isActive;
       }
  
      /** @see \Serializable::serialize() */
      public function serialize()
      {
          return serialize(array(
              $this-&gt;id,
              $this-&gt;username,
              $this-&gt;password,
              $this-&gt;isActive,
              $this-&gt;createdAt,
              $this-&gt;lastLogin,
              // see section on salt below
              // $this-&gt;salt,
          ));
      }
  
      /** @see \Serializable::unserialize() */
      public function unserialize($serialized)
      {
          list (
              $this-&gt;id,
              $this-&gt;username,
              $this-&gt;password,
              $this-&gt;isActive,
              $this-&gt;createdAt,
              $this-&gt;lastLogin,
              // see section on salt below
              // $this-&gt;salt
          ) = unserialize($serialized);
      }
  
      /**
       * Get id
       *
       * @return integer
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
      /**
       * Set username
       *
       * @param string $username
       *
       * @return User
       */
      public function setUsername($username)
      {
          $this-&gt;username = $username;
  
          return $this;
      }
  
      /**
       * Set password
       *
       * @param string $password
       *
       * @return User
       */
      public function setPassword($password)
      {
          $this-&gt;password = $password;
  
          return $this;
      }
  
      /**
       * Set email
       *
       * @param string $email
       *
       * @return User
       */
      public function setEmail($email)
      {
          $this-&gt;email = $email;
  
          return $this;
      }
  
      /**
       * Get email
       *
       * @return string
       */
      public function getEmail()
      {
          return $this-&gt;email;
      }
  
      /**
       * Set isActive
       *
       * @param boolean $isActive
       *
       * @return User
       */
      public function setIsActive($isActive)
      {
          $this-&gt;isActive = $isActive;
  
          return $this;
      }
  
      /**
       * Get isActive
       *
       * @return boolean
       */
      public function getIsActive()
      {
          return $this-&gt;isActive;
      }
  
      /**
       * Updates last user login date
       *
       */
      public function updateLastLogin()
      {
          $this-&gt;lastAccess = new \DateTime("now");
      }
  
      public function getLastLogin()
      {
          return $this-&gt;lastLogin-&gt;format('Y-m-d H:i:s');
      }
  
      public function getCreatedAt()
      {
          return $this-&gt;createdAt-&gt;format('Y-m-d H:i:s');
      }
  }
  </code></pre>
  
  <p>When the user logs in I call the <code>updateLastLogin</code> method:</p>
  
  <pre><code>&lt;?php
  namespace AppBundle\EventListener;
  
  use Symfony\Component\Security\Core\Event\AuthenticationEvent;
  use Symfony\Component\Security\Core\User\AdvancedUserInterface;
  
  class LoginListener {
  
      public function __construct(){
      }
  
      public function onSuccessfulLogin(AuthenticationEvent $event)
      {
          $user = $event-&gt;getAuthenticationToken()-&gt;getUser();
          if($user instanceof AdvancedUserInterface){
              $user-&gt;updateLastLogin();
          }
      }
  
      public function onLoginError(AuthenticationEvent $event)
      {
          // Login error
      }
  }
  </code></pre>
  
  <p>The <code>updateLastLogin</code> code is reached but it doesn't get updated in the database. Could anyone tell me what am I doing wrong?</p>
  
  <p>Thank you in advance</p>
  
  <hr>
  
  <p>The @mdma answer lead me to the right solution, with his solution I got a <code>Call to a member function getManager() on string</code> error. To solve it I just injected the <code>EntityManager</code> in the listener constructor and added the missing  call to persist the data in the database:</p>
  
  <pre><code>&lt;?php
  namespace AppBundle\EventListener;
  
  use Doctrine\ORM\EntityManager;
  use Symfony\Component\Security\Core\Event\AuthenticationEvent;
  use Symfony\Component\Security\Core\User\AdvancedUserInterface;
  
  class LoginListener {
  
      protected $entityManager;
  
      public function __construct(EntityManager $entityManager){
          $this-&gt;entityManager = $entityManager;
      }
  
      public function onSuccessfulLogin(AuthenticationEvent $event)
      {
          $user = $event-&gt;getAuthenticationToken()-&gt;getUser();
          if($user instanceof AdvancedUserInterface){
              $user-&gt;updateLastLogin();
              $this-&gt;entityManager-&gt;persist($user);
              $this-&gt;entityManager-&gt;flush();
          }
      }
  
      public function onLoginError(AuthenticationEvent $event)
      {
          // Login error
      }
  }
  </code></pre>
  
  <p>And in the <code>services.yml</code> file I added it as argument:</p>
  
  <pre><code>app.login_service:
      class:        AppBundle\EventListener\LoginListener
      arguments:    ["@doctrine.orm.entity_manager"]
      tags:
          - { name: kernel.event_listener, event: security.authentication.success, method: onSuccessfulLogin }
  </code></pre>
  
  <p>Now it works as expected. </p>
  
  <p>Notice there is a typo in the user class when updating the login date, I was using a variable which doesn't exist. Instead of <code>$this-&gt;lastAccess = new \DateTime("now");</code> it must be:</p>
  
  <pre><code>$this-&gt;lastLogin = new \DateTime("now");
  </code></pre>