beforeLogin is behaving like afterLogin

Hello,

I have a beforeLogin action that retrieves data from a third-party API, then changes the User record. The Codeless code is working as expected except for the timing. It is behaving like an afterLogin event rather than a beforeLogin event. How can I get this to execute before the user is logged in?

Hi @Stephen_Peasley,

Could you please elaborate what makes you think this event handler is acting like after login?

Regards,
Mark

The beforeLogin action changes the User record. This happens only after the user has logged in.

I’m sorry, I’m having hard time understanding. Before login is executed before Backendless performs authentication of the credentials. After login is executed after the credentials are checked.

When you say “the beforeLogin action changes the User record”, I do not understand what kind of change you’re referring to.

Sorry, maybe haven’t explained it clearly.

The desired outcome:

  1. User enters credentials to authenticate
  2. beforeLogin action retrieves data from third-party and changes User record based on result
  3. User is authenticated and can access that fetched data

What is happening:

  1. User enters credentials to authenticate
  2. User is authenticated and cannot access the fetched data
  3. beforeLogin action retrieves data from third-party and changes User record based on result

Currently, in order to access that data, the user needs to log out then log in again since it was stored after their login.

I recommend putting all your login into a try/catch block to make sure there are no errors. Also, use logging (the “print” block) to record any debug messages and check the log.

I assure you that the “beforeLogin” event handled is most certainly executed before Backendless does the authentication logic.

Regards,
Mark

1 Like

Thanks, @mark-piller. My login is already in a try/catch block and I have no errors. Or do you mean to do that in Codeless?

Yes, I am referring to the Codeless logic you showed at the top of this topic. Wrap the whole thing into a try catch block and make sure to log any errors.

Gotcha, thanks.

Hm, no errors from the try/catch and the traced output is showing what is expected. I’m scratching my head as to what’s going on here.

I think your Codeless logic is wrong.

What is “identify” in your Users table setup? Is it just an email?

Yes, it’s an email.

The logic executes as intended: it grabs the user based on the email, fetches the data from Stripe, then stores that data on the User object. It seems like a race condition issue but the try/catch and trace statements didn’t give me any insight into that.

Is the subscription property updated in the user object in the database?

Btw, it would make a lot more sense to move that logic to the afterLogin event handler. This is for the reason is the user is not authenticated at the point where you added logic and the credentials might be wrong. So you could be updating a user even when they provided a wrong password. In the afterLogin event handler, you can check if the authentication succeeded and only then do the thing you’re doing.

However, let’s focus on getting the logic fixed up first.

Yes, the logic executes as intended and the subscription property is updated appropriately. It’s okay if the credentials are wrong, as this just synchronizes the user with the Stripe subscription data.

If the user object is updated, that’s great. The only thing I am not sure about is the return statement at the very end. Could you try removing that “currentUser” variable from return? Leave the return empty, I think it is not needed and is messing things up.

I had the same though and tried it but it made no difference. It’s an odd problem.

So in the description of what’s happening you said this:

So after the user is authenticated, are you loading some data? Where is that “fetched data” coming from?

The desired outcome:

  1. User enters credentials to authenticate
  2. beforeLogin action retrieves data from third-party (Stripe) and changes User record based on result
  3. User is authenticated and can access that fetched data (subscription, which came from Stripe)

What I currently see:

  1. Looking at the data in Backendless, the user’s subscription column is empty (which is correct)
  2. The user logs authenticates and their User object is returned
  3. Looking at the data in Backendless, the user’s subscription column is correctly populated (but that state was not returned to the authenticated user).

I hope that makes sense.

What is the data type of the subscription column?
Did you remove the return statement and redeploy the event handler?

The subscription column is text and it stores stringified JSON.

Yes, I removed the return statement and redeployed the event handler.

Please let me know your application ID and username/password for a test user account I can try it with.