BackendlessException{ code: 'Internal client exception', message: 'null' } at update(user)

Hi!

At one point in my app, a user clicks a button to change one of their backendless properties. Here is my code:

public class MainActivity extends Fragment implements View.OnClickListener {


    private ImageButton customToggle;
    private FragmentManager fm;
    private BackendlessUser user;


    public enum Status {
        UNAVAIL, AVAIL, ACT
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


//        FacebookSdk.sdkInitialize(main.getApplicationContext());


        fm = getFragmentManager();
        user = Backendless.UserService.CurrentUser();
        user.setProperty("Status", "UNAVAIL");


        String appVersion = "v1";
        Backendless.initApp(getContext(), getResources().getString(R.string.backendless_app_id), getResources().getString(R.string.backendless_secret_key), appVersion);


        View rootView = inflater.inflate(R.layout.activity_main, container, false);
        customToggle = (ImageButton) rootView.findViewById(R.id.custom_toggle_button);
        customToggle.setOnClickListener(this);
        return rootView;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();


        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }


        return super.onOptionsItemSelected(item);
    }


    public static MainActivity newInstance() {
        MainActivity activity = new MainActivity();
        return activity;
    }


    public String getStatus() {
        return (String) user.getProperty("Status");
    }


    public void onClick(View v) {
        if (v.getId() == R.id.custom_toggle_button) {
            try {
                user.setProperty("Status", Status.AVAIL.toString());
                user = Backendless.UserService.update(user);
            } catch (BackendlessException e) {
                Toast.makeText(getContext(), "Error: " + e + "Code is " + e.getCode(), Toast.LENGTH_LONG).show();
            }
            Toast toast = Toast.makeText(getContext(), "You are available!", Toast.LENGTH_SHORT);
            toast.show();
        }
    }
}


For some reason, line 59 gives the error I listed in the title. Any ideas why or how to fix it?

This is on Android, by the way.

You’re making a synchronous call on the main UI thread in Android right here:

Backendless.UserService.update(user);

Please see the section marked as “Important” on this page in the docs:
https://backendless.com/documentation/users/android/users_sync_and_async_api.htm

Thanks Mark! It seems unclear to me how I would make the call asynchronously. Could you help me out?

The documentation includes an example of the asynchronous API call:

https://backendless.com/documentation/data/android/data_updating_data_objects.htm

I changed my code to this:

public class MainActivity extends Fragment implements View.OnClickListener {

    private ImageButton customToggle;
    private FragmentManager fm;
    private BackendlessUser user;

    public enum Status {
        UNAVAIL, AVAIL, ACT
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//        FacebookSdk.sdkInitialize(main.getApplicationContext());

        fm = getFragmentManager();
        user = Backendless.UserService.CurrentUser();
        user.setProperty("Status", "UNAVAIL");

        String appVersion = "v1";
        Backendless.initApp(getContext(), getResources().getString(R.string.backendless_app_id), getResources().getString(R.string.backendless_secret_key), appVersion);

        View rootView = inflater.inflate(R.layout.activity_main, container, false);
        customToggle = (ImageButton) rootView.findViewById(R.id.custom_toggle_button);
        customToggle.setOnClickListener(this);
        return rootView;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public static MainActivity newInstance() {
        MainActivity activity = new MainActivity();
        return activity;
    }

    public String getStatus() {
        return (String) user.getProperty("Status");
    }

    public void onClick(View v) {
        if (v.getId() == R.id.custom_toggle_button) {
            try {
                user.setProperty("Status", Status.AVAIL.toString());
                Backendless.UserService.update(user, new AsyncCallback<BackendlessUser>() {
                    @Override
                    public void handleResponse(BackendlessUser response) {

                    }

                    @Override
                    public void handleFault(BackendlessFault fault) {

                    }
                });
            } catch (BackendlessException e) {
                Toast.makeText(getContext(), "Error: " + e + "Code is " + e.getCode(), Toast.LENGTH_LONG).show();
            }
            Toast toast = Toast.makeText(getContext(), "You are available!", Toast.LENGTH_SHORT);
            toast.show();
        }
    }
}

I no longer get the error, but the user property “Status” still isn’t updating

The property is not updating on the server?

No it’s not. I’ve actually changed the code so that the ImageButton is now a ToggleButton and the OnClickListener is instead OnCheckedChangeListener, but that problem still remains.

I have set the default status at UNAVAIL, and it is stuck on that. Is there any chance the fact that it is the default is the problem?

Try setting a breakpoint in your app on the following line and check what properties the user object contains before it is sent to the server by the update method.

Backendless.UserService.update(user, new AsyncCallback<BackendlessUser>() {

Huh. The debugger does say AVAIL

Perhaps there is a fault with the object update. Please modify the handleFault method as shown below and see (in the debugger) if you’re getting a fault:

public void handleFault(BackendlessFault fault) {
Toast.makeText(getContext(), "Error: " + fault.toString(), Toast.LENGTH_LONG).show();
}

I was given this message:

"Error: BackendlessFault{ code: ‘2002’, message: ‘Version is disabled or provided wrong application info (application id or secret key)’ }

I already checked that both the application id and secret key were correct, so I don’t know what the problem is otherwise.

It must be something with your initApp call, the error you get is related to the wrong credentials. Is there a possibility that you’re using the wrong secret key? For example, BL one for Android app or like that. If that’s definitely not the case, please provide the application ID, secret key and version you are using.