Skip to main content

Command Palette

Search for a command to run...

Avatar image in Oracle APEX

Using a REST Media Resource as an image source

Updated
3 min read
Avatar image in Oracle APEX

Why you should read this

Displaying custom avatar images in Oracle APEX’s top navigation bar isn't as straightforward as you might think. By default, APEX lets you use Font APEX icons, but replacing those with actual image - especially ones stored as BLOBs in database - it takes some extra work.

In this post, I've put down the steps to do that using a REST Media Resource as the image source for your avatar, which is one of the simplest and most flexible approaches.

There are a few other possible methods that you can use:

  • Third-party services that host avatar images and provides image URLs via API (such as Gravatar, used by the APEX Ideas App)

  • Hosting your avatars in the APEX Static Application Files

  • Converting your avatar images to Base64-encoded image URLs

Each of these alternatives has its pros and cons and will try to cover them in more detail in future blog post. For now, let’s see how the REST Media Resource approach can help us in achieving our goal.

Step by step guide

  1. REST Module with a GET method, Source type - Media Resource

DECLARE
  l_roles     OWA.VC_ARR;
  l_modules   OWA.VC_ARR;
  l_patterns  OWA.VC_ARR;

BEGIN
  ORDS.ENABLE_SCHEMA(
      p_enabled             => TRUE,
      p_url_mapping_type    => 'BASE_PATH',
      p_url_mapping_pattern => 'gamma_dev',
      p_auto_rest_auth      => FALSE);

  ORDS.DEFINE_MODULE(
      p_module_name    => 'profile',
      p_base_path      => '/profile/',
      p_items_per_page => 25,
      p_status         => 'PUBLISHED',
      p_comments       => NULL);

  ORDS.DEFINE_TEMPLATE(
      p_module_name    => 'profile',
      p_pattern        => 'profile_picture/:user_id',
      p_priority       => 0,
      p_etag_type      => 'HASH',
      p_etag_query     => NULL,
      p_comments       => NULL);

  ORDS.DEFINE_HANDLER(
      p_module_name    => 'profile',
      p_pattern        => 'profile_picture/:user_id',
      p_method         => 'GET',
      p_source_type    => 'resource/lob',
      p_mimes_allowed  => NULL,
      p_comments       => NULL,
      p_source         => 
'select mime_type as content_type, blob_content from MY_USERS_TABLE where id = :user_id');

  ORDS.DEFINE_PARAMETER(
      p_module_name        => 'profile',
      p_pattern            => 'profile_picture/:user_id',
      p_method             => 'GET',
      p_name               => 'user_id',
      p_bind_variable_name => 'user_id',
      p_source_type        => 'URI',
      p_param_type         => 'STRING',
      p_access_method      => 'IN',
      p_comments           => NULL);


COMMIT;

END;

  1. Desktop Navigation Bar entry

<img id="user_avatar_img" class="ea-topnav-avatar" src="https://oracleapex.com/ords/gamma_dev/profile/profile_picture/&G_USER_ID."></img>

  1. Application Item with the User_ID, used in the REST module

  1. Add CSS to style the navigation

/* Navigation Bar avatar fixes */
.t-NavigationBar {
    align-items: center;
}

.ea-topnav-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px #6b3010 solid;
}

@media (max-width:768px) {
    .ea-topnav-avatar {
        width: 32px;
        height: 32px; 
    }
}

@media (max-width:479px) {
    .ea-topnav-avatar {
        margin-right: 20px;
    }

    .t-NavigationBar {
        column-gap: 25px;
    }
}

.t-Button--navBar .t-Button-badge {
    display: flex;
    border-radius: 50%;
    padding: 0;
    background: none;
}
  1. See your avatar in action

Security

  1. Instead of just USER_ID, use a hashed version on the User_id + User_Email or any other columns in your user table

  • Create new Application Item, called G_USER_HASH

  • Compute G_USER_HASH after Authentication (using Application Process or Application Computation). Here is a sample code for a hashing that you could use:

      select mime_type content_type, profile_image blob_content 
      from my_users_table 
      where apex_util.get_hash(apex_t_varchar2 (id, user_email)) = :user_hash
    
  1. Modify the REST module to use the G_USER_HASH, instead of just user_id

  • Change the Resource Template, replacing :user_id with :user_hash parameter (similar to the below):

  • Change the GET method Source and Parameter name:

      select mime_type content_type, profile_image blob_content 
      from my_users_table 
      where apex_util.get_hash(apex_t_varchar2 (id, user_email)) = :user_hash