cloud.registerUser frustration

Hope this will help some developers to save some time and frustration.

If you call cloud.registerUser you will get no event.error if:

a) the username already exists

b ) the email already exists

c) the password is shorter than 6 characters

In the documentation the first 2 cases are mentioned, but not the third.

Here is the code I use for registration (I treat all 3 as errors):

function authListener( event )     if ( event.type == "registerUser" ) then         if not ( event.error ) then             -- in the docs:             --handle a successful registration; consider logging them in from here            -- wrong ! you are not safe here for login             registrationHandler(event)         else             --code to handle registration failure             native.showAlert( "Registration Error!", event.error, {OK} )         end end function registrationHandler( event )     local r = json.decode(event.response)     if(r.base~=nil and r.base[1] ~= nil) then -- this is for to short pwd         native.showAlert( ERROR,  r.base[1] ..  ".", { OK })     elseif(r.username~=nil and r.username[1] ~= nil) then         native.showAlert( ERROR, USERNAME .. " " .. r.username[1] ..  ".", { OK })     elseif(r.email~=nil and r.email[1] ~= nil) then         native.showAlert( ERROR, EMAIL .. " " .. r.email[1] .. ".", { OK })     else         native.showAlert( INFOS, "Account created.", { OK })     -- now you can login!     end end  

Good to know about the password being too short.  If you are creating your own forms to input this data, you should validate the data before you attempt to register.  Make sure the email address is formatted properly (see the blog post on strings two weeks ago).  Make sure the password meets the minimum length.  Then when you have clean data, then try to register.

WoW, this one is nasty:

If you have a uppercase letter in your email, you get no error, you get the response (without email field!) but you can not login, you will get " Username or password is incorrect".

And username is even not the problem here, it is the email.

Hi,

The accounts shouldn’t be case sensitive, but I’ll get the team to look into this ASAP.

Thanks

-Mohamed

Good to know about the password being too short.  If you are creating your own forms to input this data, you should validate the data before you attempt to register.  Make sure the email address is formatted properly (see the blog post on strings two weeks ago).  Make sure the password meets the minimum length.  Then when you have clean data, then try to register.

WoW, this one is nasty:

If you have a uppercase letter in your email, you get no error, you get the response (without email field!) but you can not login, you will get " Username or password is incorrect".

And username is even not the problem here, it is the email.

Hi,

The accounts shouldn’t be case sensitive, but I’ll get the team to look into this ASAP.

Thanks

-Mohamed

Hi!

I can confirm this bug;  When registration fails due to existing username or password, event.isError is nil!

I hope the Corona people will fix this asap!

Are you using cloud.lua or corona-cloud-core.lua or the REST API?

Where are you seeing event.isError = nil?  In the event handler of your authListener or are you seeing this in the cloud.lua code?

Hi Rob,

I’m using the latest cloud.lua from https://github.com/coronalabs/framework-cloud.

This is the event data I’m receiving in authListener from the cloud.registerUser call using an invalid username and password:

event.type: registerUser     event.isError: nil     event.response: {"username":["has already been taken"],"base":["Password must be at least 6 chars long"]}

Corona version 2013.1131

Please read my first post. Everything is explained there.

I had to use some “tricks” to compensate for this bug.

Hi Ubj3d, thanks for making this post in the first place. I appreciate your work around and will use it for now, but I got the impression that Corona hasn’t really grasped this error.

Corona staff response to your post was to sanity check before calling registerUser but they didn’t mention anything about the isError being nil, so I want to try to shed some more light on this issue.

Hi @ubj3d.android.  I’m not patronizing you.  I didn’t see (and still don’t) in your OP any where in your code where you are checking the value of event.isError.  My response was really to @Joel_DGS as I’m trying to isolate where this error is happening.  But let me explain a little bit while this appears to not be working, though it’s working correctly.

All of the cloud.lua (and the previous corona-cloud-core.lua) are based about our network.request() API call.  When this API call executes it’s listener function and passes in the event table, event.isError will be set to true if the device is in Air Plane mode, or if gets a time out (the server is down) or some other network connection.   This is not a general “isError” message to catch things from Corona Cloud (or any web based URL) that doesn’t return the results you expect.  For example,  if you try to do a network.request() to the URL:  http://coronalabs.com/bluberdybloop.html, the web server will generate a 404 error, but this is the important thing:  The request was successful!   404, 500, and other error response codes are successful returns from the web server.  You have to look at the event.response to see what the return code is and react to that to see if the resulting data is not what you’re expecting.

So in this case, an invalid username, too short of a password, etc.  is a successful return and event.isError will be nil.

The data structure returned from cloud.lua does not contain event.isError anyway.  In cloud.lua if we see a network request that times out (event.isError) then we set your event.error to the network request event.response and set your event.response to nil.   If we don’t detect a network error (even if its a 404 or  some other thing like username taken), then your event.error is set to nil and your event.response contains the data returned from the call.

Hope that helps you understand a bit on what’s going on here.

It is not clear to me, do we use event.isError or event.error ?

Also, how should we handle the 3 “not errors” in your scenario:

a) the username already exists

b ) the email already exists

c) the password is shorter than 6 characters

Regards,

Damir.

@Rob: Thanks for responding. I was actually going to post about the fact that event.isError is internal to the cloud.lua module and not mentioned in the API. I found out a bit late and I guess I mixed things up as I’m also doing a lot of network.request() stuff. It makes sense to me now: Forget about event.isError in this case.

But just like ubj3d, the fact (or bug if you will) still stands;

According to Corona Docs: http://docs.coronalabs.com/guide/cloud/manageUsers/index.html#register:

If event.error is true, the most common cause is that the supplied email address has already been registered.

This appears to be false.  As a matter of fact, in the cases described in the OP, the event.response contains the “error message” while event.error is nil (which makes sense because in cloud.lua event.isError was nil in the first place). But it is not what the quote from the guide above is telling us, even if it’s a bit sparse on the topic to say the least!

So, I would still like to know what is the best practice for handling failed registerUser() attempts. To be matching strings or checking undocumented property keys doesn’t feel like a solid way of doing business.

I noticed that a successful registration returns an id (or perhaps _id) property key, while a failed attempt does not, or so it seems. But I don’t know if only checking for this is safe as I can’t find any return specifications for successful nor unsuccessful attempts (i.e this could be changed in the future).

Please advise.

Joel

Looks like some mis-understanding got through the review process on the guide.  Anyway, here is what gets returned in event.response:

This is a failure

table: 0x10f9f38c0 {    [type] =\> "registerUser"    [name] =\> "authentication"    [response] =\> "{"username":["has already been taken"],"email":["is already taken"],"base":["Password must be at least 6 chars long"]}" }

If you json.decode(event.response) it looks like username, email, and/or base will be a table with a single entry in it.  BTW: This shows all three failures.  So some code like:

        if event.error == nil then             local r = json.decode(event.response)             if r.email then                  print("email " .. r.email[1])             elseif r.base then                  print("password " .. r.base[1])             elseif r.username and type(r.username) == "table" then                  print(username .. r.username[1])             else                 print("login after successful registration")                 local loginParams = {}                 loginParams.type = "user"                 loginParams.email = settings.email                 loginParams.password = settings.password                 cloud.login( loginParams )             end         else            print("Some network error happened")         end

I tested this in one of my apps and it seems to catch the right things.  A successful register returns this table of information:

 table: 0x11007b9f0 {    [type] =\> "registerUser"    [name] =\> "authentication"    [response] =\> "{"\_id":"51bcdb87ba187bc75800001f","achievements":null,"activated\_at":null,"active":false,"city":null,"country":null,"created\_at":"2013-06-15T21:24:23+00:00","facebook\_enabled":null,"facebook\_id":null,"first\_name":"iap","game\_ids":["51324a0a649329244f000002"],"last\_device\_used":null,"last\_game\_played":null,"last\_login":null,"last\_name":"iap","location\_lat":null,"long\_coords":null,"notification\_channel\_ids":[],"points":0,"profile\_picture\_content\_type":null,"profile\_picture\_file\_name":null,"profile\_picture\_file\_size":null,"profile\_picture\_updated\_at":null,"remember\_token":null,"remember\_token\_expires\_at":null,"reset\_code":null,"signed\_up\_from\_facebook":false,"twitter\_access\_secret":null,"twitter\_enabled":null,"twitter\_id":null,"updated\_at":"2013-06-15T21:24:23+00:00","username":"iap04z"}" }

 

Note, the password and email will never be set in a successful return.  Also the username entry is a string, not a table.

Rob

Hi!

I can confirm this bug;  When registration fails due to existing username or password, event.isError is nil!

I hope the Corona people will fix this asap!

Are you using cloud.lua or corona-cloud-core.lua or the REST API?

Where are you seeing event.isError = nil?  In the event handler of your authListener or are you seeing this in the cloud.lua code?

Hi Rob,

I’m using the latest cloud.lua from https://github.com/coronalabs/framework-cloud.

This is the event data I’m receiving in authListener from the cloud.registerUser call using an invalid username and password:

event.type: registerUser     event.isError: nil     event.response: {"username":["has already been taken"],"base":["Password must be at least 6 chars long"]}

Corona version 2013.1131

Please read my first post. Everything is explained there.

I had to use some “tricks” to compensate for this bug.