How do I show an already hidden field of a custom content type to a specific authenticated user? I have a custom content type whose fields are Name, Description, and URL which is hidden by default. I want to show the latter field to the authenticated users who have flagged the node containing it. (I installed the Flag module for the flags.)
The flagging and displaying the flagged items are working fine. The only thing I am having trouble with is the hidden URL.
Can anyone guide me on how I can do this?
I looked into using the Rules and the Conditional Fields modules, but I don't think they would help and they seem to be an overkill for this particular task. I also looked into implementing hook_page_alter(), but that didn't help either.
It's possible to hide/show an entity field when an entity is rendered, but a hidden field is automatically removed from the base class used to implement an entity view, the EntityDisplayBase class. Its constructor calls EntityDisplayBase::init(), which contains the following code.
// @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
if (!isset($options['region']) &amp;&amp; !empty($options['type']) &amp;&amp; $options['type'] === 'hidden') {
  $options['region'] = 'hidden';
  @trigger_error(&quot;Support for using 'type' =&gt; 'hidden' in a component is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use 'region' =&gt; 'hidden' instead. See https://www.drupal.org/node/2801513&quot;, E_USER_DEPRECATED);
}
if (!empty($options['region']) &amp;&amp; $options['region'] === 'hidden') {
  $this
    -&gt;removeComponent($name);
}

Since that code is executed when the entity display class is build, every hook running before the entity is rendered would not get those hidden components (which are entity fields and extra fields).
Rather than setting an entity field as hidden by default, and then show it when some conditions are met (which would not be possible), you can set the field as visible by default, and hide it when some conditions are met. Which hook to use depends also from when that field needs to be hidden.
If the entity field needs to be hidden only when specific view modes (a.k.a. entity display modes) are used, then hook_entity_view_display_alter() can be implemented.
use \Drupal\Core\Entity\Display\EntityViewDisplayInterface;

function mymodule_entity_view_display_alter(EntityViewDisplayInterface $display, array $context) {
  // Leave field labels out of the search index.
  if ($context['entity_type'] == 'node' &amp;&amp; $context['view_mode'] == 'the view module you are interested to') {
    $components = $display-&gt;getComponents();
    $name = 'The machine name of the field you want to hide.'
    if (isset($components[$name])) {
      $options = $components[$name];
      // Verify the conditions to hide the field are met.
      $options['region'] = 'hidden';
      $display-&gt;setComponent($name, $options);
      }
    }
  }
}

The code I shown assumes you are using at least Drupal 8.3; otherwise, it needs to be changed. (Instead of $options['region'], it needs set $options['type'] to 'hidden'`.)
If you need to hide the field independently from the view mode used to render the node, then the hook to implement is hook_entity_field_access().
use \Drupal\Core\Field\FieldDefinitionInterface;
use \Drupal\Core\Field\FieldItemListInterface;
use \Drupal\Core\Session\AccountInterface;

function mymodule_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
  if ($field_definition-&gt;getName() == 'the field you are interested to' &amp;&amp; $operation == 'view') {
    // Verify the conditions to hide the field are met.
    // Return AccessResult::forbidden() if the conditions are met.
    return AccessResult::forbidden();
  }
  // Otherwise, return AccessResult::neutral(), which lets Drupal core
  // or third-party modules decide.
  return AccessResult::neutral();
}

I used AccessResult::forbidden() just as example. You could also verify the account passed to the hook has a specific permission with AccessResult::allowedIfHasPermission($account, 'permission to check'), or verify the account has one or more permissions with AccessResult::allowedIfHasPermissions($account, ['list', 'of', 'permissions'], 'OR').
Keep in mind that, implementing hook_entity_field_access(), you would also avoid the field is indexed by the Search module. If you want the field to be indexed by the Search module, you need to implement hook_entity_view_display_alter() and leave the field visible when $context['view_mode'] is equal to 'search_index'.
As alternative, you could create a view mode that is similar to the view mode used to show the node, but where the hidden field is visible. Implementing hook_entity_view_mode_alter() you can alter the view mode to use the one you created.
use Drupal\Core\Entity\EntityInterface;

function mymodule_entity_view_mode_alter(&amp;$view_mode, EntityInterface $entity, $context) {
  // For nodes, change the view mode when it is teaser.
  if ($entity-&gt;getEntityTypeId() == 'node' &amp;&amp; ($view_mode == 'full' || $view_mode == 'teaser')) {
    // Verify the conditions are met.
    $view_mode = 'my_custom_view_mode';
  }
}