Why is code executed in different order in Auth0 Actions?

Im writing an action to update user metadata which is a phone number field. I get the phone number form the management api which helps me retrieve the mfa phone number. However, due to some issues I am not able to set the user metadata. I think its due to race condition, not sure. I can see the logs when I do a console log, but when I call the set user metadata I get empty string.

/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
const ManagementClient = require('auth0').ManagementClient;
exports.onExecutePostLogin = async (event, api) => {
     const AUTH0_MANAGEMENT_API_STATE =  new ManagementClient({ domain: event.secrets.domain, clientId: event.secrets.ClientId,clientSecret: event.secrets.ClientSecret,scope: 'read:users update:users'}); //ALl states should subscribe to management api and should have client grant permission and update user and metadata and guardiaan read and delete scope

     console.log("Get User Details Action Started");

	 const namespace = vent.secrets.namespace;
     api.user.setUserMetadata('PhoneNumber', await getPhoneNumber(AUTH0_MANAGEMENT_API_STATE, event.user.user_id));


	 var PhoneNumber= event.user.user_metadata['PhoneNumber'];
   if (event.authorization) {
    // Set claims 
   
    api.idToken.setCustomClaim(`${namespace}/phoneNumber`,PhoneNumber);
   console.log("Logged in Event should be seeen here!!!")
  }
};

async function getPhoneNumber(AUTH0_MANAGEMENT_API_STATE, id, user) 
     {
          await AUTH0_MANAGEMENT_API_STATE.getGuardianEnrollments({ id}, function (err, enrollments) {
               if(err){
                    console.log("There was an error calling get Gaurdian Enrollment");
                    console.log("THis is the error", err);
               }

               console.log("Enrollment from get user detail",enrollments[0]);
               return enrollments[0].phone_number;
          });
     }

/**
* Handler that will be invoked when this action is resuming after an external redirect. If your
* onExecutePostLogin function does not perform a redirect, this function can be safely ignored.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/


// exports.onContinuePostLogin = async (event, api) => {
// };

Hi spoudel,

Are you using custom database in auth0. Auth0 always trigger get, create and login script asynchronously during the create operation. This need to be happen because it need to check whether user present in external db, and create user in external db and finally triggering login verify the user is being create sucessfully.

I am not using a custom database. I get its an asynchronous call, but I have set a promise which should set the usermetadata once management client api responds.

Hi @spoudel,

Thanks for reaching out to the Auth0 Community!

I understand that you have encountered some issues with setting the user’s user_metadata in a Post Login Action.

Unfortunately, the Post Login Action executes synchronously as described in our doc here. With that, I recommend using synchronous calls so that there’s an order of execution to ensure that you get the user’s phone number before setting it into the user_metadata and then setting it as a custom claim.

Please let me know how it goes for you.

Thanks,
Rueben

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.