Why string array can't be added to backendless user?

I tried to add a string array to my backendless user but I get this error every time, doesn’t matter if the array is empty or not.

E/BackendlessError: BackendlessFault{ code: '8044', message: 'Cannot save entity with primitive collection property friendIdList' }


Here is my code:

ArrayList<String> friendIdList = new ArrayList<String>();
friendIdList.add(user.getObjectId());
user.setProperty("friendIdList", friendIdList);

Why am I not allowed to add primitive collection properties?

Backendless does not support arrays of primitive (or string) values. However, you could declare your column and String and store JSON objects there (as strings).

Do you plan to add that feature? Adding strings to json and then having to parse them each time I want to get something from that array seems like too much overhead for something that simple. It would be much easier if it were built into backendless, so the developer doesn’t have to deal with it every time when storing and getting data from it.

We might consider adding it. I personally do not like it because it re-enforces a bad practice from the database perspective.

Then what would you suggest if I want to save other users Ids like a friends feature on facebook, how best to implement it?

How about creating a relation column called “friends” and point it to the Users table?

That’s what I tried at first, making three columns which point to Users table, one for friend requests to user, one for sent friend requests and one for the friend list. But I have problems updating those columns. For example sometimes backendless returns the type of Object[], or BackendlessUser[] and sometimes my app crashes because it returns ArrayList.

When a related collection is empty, it returns Object[] (as a part of BackendlessUser object). When data is there, it would return BackendlessUser[]. I am not aware of any use cases when a related property in BackendlessUser would be ArrayList.

What if you add the property like this?

ArrayList<BackendlessUser> friends = new ArrayList<BackendlessUser>();
currentUser.setProperty(friends);

Will it return ArrayList or BackendlessUser[] ?

It will return BackendlessUser[]

So when I want to get the value do I have to first check length and then cast it with something like this:

Object[] objectList = user.getProperty("friends");
if(objectList.length>0){
BackendlessUser[] friends  = (BackendlessUser[]) objectList;
}

Or I can directly cast it to BackendlessUser[]?

You should check the length first. The reason for that is when there is no data, our library does not know how to “materialize” the collection (meaning what data type to use for it). As a result, it creates it as Object[].

Now I get just this in the log, user update callback fails and in the log is this line:

 E/BackendlessError: BackendlessFault{ code: 'IllegalArgumentException', message: 'java.lang.Object[] cannot be cast to java.util.Map' }

Which call results in this error?Is there a stack trace with the error?

No stack trace, just simple update call

Backendless.UserService.update(currentUser,DefaultCallback<BackendlessUser>(context));

What do you have in the currentUser object right before you call the update method? Could you set a breakpoint and take a screenshot of the currentUser contents in the debugger?

BackendlessUser[] requests = new BackendlessUser[requestsList.size()];
requests = requestsList.toArray(requests);
currentUser.setProperty(BackendlessUserProperties.REQUESTS, requestsList);

This is what I change in the user right before the update

Thanks. Are there any other properties in the “currentUser” object and in each of the objects in the “requests” array?

No, I have only changed the requests column, which is related to User

I am going to try to reproduce the error. Just to make sure I do not miss anything, could you please attach a screenshot showing the currentUser object hierarchy (all expanded) right before the “update” method is called?