I have extended the ‘BackendlessUser’ class in order to get/set custom properties.
When I login and attempt to cast the returned ‘BackendlessUser’ object to my custom ‘User’ class, I am getting a “ClassCastException”. Is it possible to do this?
public class User extends BackendlessUser {
public static final String FIRST_NAME = "firstName";
public static final String LAST_NAME = "lastName";
public static final String PHONE_NUMBER = "phoneNumber";
public User() {
}
public String getFirstName() {
return (String) getProperty(FIRST_NAME);
}
public void setFirstName(String firstName) {
setProperty(FIRST_NAME, firstName);
}
public String getLastName() {
return (String) getProperty(LAST_NAME);
}
public void setLastName(String lastName) {
setProperty(LAST_NAME, lastName);
}
public String getPhoneNumber() {
return (String) getProperty(PHONE_NUMBER);
}
public void setPhoneNumber(String phoneNumber) {
setProperty(PHONE_NUMBER, phoneNumber);
}
public Credentials getCredentials() {
return new Credentials(
getEmail(),
getPassword()
);
}
}
Generally speaking extending BackendlessUser is not a good idea. However, it is possible for most operations, with a glaring exception of the login API - it simply will not return an instance of your subclass (the login will be performed though). The key to creating a subclass is a mapping between your class which is a subclass of BackendlessUser and the Users table. The mapping is done with the following API:
Where “MyUser” is a subclass of BackendlessUser in my example which follows. First off the MyUser class:
package com.mbaas;
import com.backendless.BackendlessUser;
public class MyUser extends BackendlessUser
{
public static final String PHONE_NUMBER = "phoneNumber";
public static final String NAME = "name";
public String getPhoneNumber()
{
return (String) getProperty( PHONE_NUMBER );
}
public void setPhoneNumber( String phoneNumber )
{
setProperty( PHONE_NUMBER, phoneNumber );
}
public String getName()
{
return (String) getProperty( NAME );
}
public void setName( String name )
{
setProperty( NAME, name );
}
}
Now, here’s a little command prompt program demonstrating how it would work. Please keep in mind that in an Android app, you’d need to use the async calls for the API when calling on the main UI thread:
package com.mbaas;
import com.backendless.Backendless;
import com.backendless.BackendlessCollection;
import com.backendless.persistence.BackendlessDataQuery;
public class CustomUserObjectTest
{
public static void main( String[] args )
{
String APPLICATION_ID = "PUT-YOUR-APP-ID-HERE;
final String SECRET_KEY = "YOUR-ANDROID-SECRET-KEY";
Backendless.initApp( APPLICATION_ID, SECRET_KEY, "v1" );
Backendless.Data.mapTableToClass( "Users", MyUser.class );
registerUser();
login();
loadUserObject();
}
public static void registerUser()
{
MyUser user = new MyUser();
user.setPhoneNumber( "555-1212" );
user.setName( "JamesBond" );
user.setPassword( "password" );
Backendless.UserService.register( user );
}
public static void login()
{
// THIS WILL NOT WORK - LOGIN ALWAYS RETURNS BackendlessUser
MyUser myUser = (MyUser) Backendless.UserService.login( "JamesBond", "password" );
System.out.println( "user is logged in " + myUser.getName() );
}
public static void loadUserObject()
{
BackendlessDataQuery query = new BackendlessDataQuery();
query.setWhereClause( "name = 'JamesBond'" );
BackendlessCollection<MyUser> users = Backendless.Data.of( MyUser.class ).find( query );
System.out.println( "user - " + users.getCurrentPage().get( 0 ).getName() );
}
}
I tried to do the similar thing, except that the phone number is the identity column in the Users table, in Swift. But apparently it doesn’t work. I keep getting the error “Unable to register user. Missing identity value for ‘phone’” even after setting the correct value in the phone attribute. Can you please provide a code-snippet in Swift too?