V.4: Can't retrieve full nested list

Hey guys,
I’ve added

compile 'com.backendless:backendless:4.0.0-beta3'

I have HPMPreference object with list of AndroidId objects (one to many). Quantity of AndroidId is 158.
On backendless v.3 I got all these objects and for now in v.4 I can’t to retrieve full nested list from object. It gives me only 10 objects. How to fix it?
Also I can’t find any documentation about it.

 Backendless.Persistence.of(HPMPreference.class).findFirst(new AsyncCallback<HPMPreference>() {
 @Override
 public void handleResponse(HPMPreference preference) {
 }
 @Override
 public void handleFault(BackendlessFault backendlessFault) {
 }
 });
public class HPMPreference {
 public List<AndroidId> androidIDs;
}

Hello, Oleg,

you have to use load relation method with relation paging https://backendless.com/docs/android/doc.html#data_relation_paging

Hi Sergey, thank you for your response!

Seems it’s not what I need. Correct me if I’m wrong.

Can you look at the attached screenshot, please?
You will see preference object with nested list whiteList and nested object advertise with nested list banners.
I want to retrieve more than 10 objects for both lists in one request from my side when I get preference object.

Hi Oleg,

No, this is exactly what you need. In 3.x server returned all related objects, which created a big problem for server stability. Now in 4.x related objects are returned using paged format, that is only a block of objects at a time. In order to retrieve additional related objects, you need to use the API which Sergey has referenced.

Mark

Thank you Mark, I got it.

Does it mean that I have on 3.x a few of code:

NPreference preference = Backendless.Data.of(NPreference.class).findById(BACKENDLESS_PREFERENCE_ID);

And on 4.x I should to write a huge portion of code and a lot of requests and my user will lose more time for all requests? Please tell me that I’m wrong and code provided below is a mistake.

final int PORTION = 25;
int pages = PORTION;
int offset = 0;
List<AndroidId> whiteList = new ArrayList<>();
List<Banner> banners = new ArrayList<>();

NPreference preference = Backendless.Data.of(NPreference.class).findById(BACKENDLESS_PREFERENCE_ID);

// retrieve white list
do {
    LoadRelationsQueryBuilder<AndroidId> whiteQueryBuilder = LoadRelationsQueryBuilder
            .of(AndroidId.class)
            .setPageSize(pages)
            .setOffset(offset)
            .setRelationName("whiteList");
    List<AndroidId> temp = Backendless.Data.of(NPreference.class).loadRelations(preference.getObjectId(), whiteQueryBuilder);
    whiteList.addAll(temp);

    offset = pages;
    pages += PORTION;

} while (ListUtil.isNotEmpty(whiteList));

preference.whiteList = whiteList;

Advertise advertise = preference.advertise;
if (advertise != null && !TextUtils.isEmpty(advertise.getObjectId())) {

    // retrieve banners list
    pages = PORTION;
    offset = 0;
    do {
        LoadRelationsQueryBuilder<Banner> bannerQueryBuilder = LoadRelationsQueryBuilder
                .of(Banner.class)
                .setPageSize(pages)
                .setOffset(offset)
                .setRelationName("banners");
        List<Banner> temp = Backendless.Data.of(Advertise.class).loadRelations(advertise.getObjectId(), bannerQueryBuilder);
        banners.addAll(temp);

        offset = pages;
        pages += PORTION;

    } while (ListUtil.isNotEmpty(banners));
    preference.advertise.setBanners(banners);
}

If you need to return all the objects to the client app at once, you could consolidate the logic for data retrieval in a custom API service. The service would be responsible for retrieving all the data (or as many objects as needed by making multiple API calls) and then returning the data to the client. From the client’s perspective it would be a single call. However, the data would still need to be retrieved in the paging fashion - at most 100 objects at a time.

Regards,
Mark

Thanks again for your help. Seems I will stay on 3.x, because 4.x is ugly and not for developers (( I want to focus on my work and not on the backend code.
I’m going to buy 3.x. If price for 3.x will be increased - I will go to firebase (((( But I really like 3.x !

I am glad you like 3.x, but many people would disagree with you about 4.0. You are definitely entitled to an opinion and I respect that.

Mark, can you please help with understanding how much I need to pay for 3.x version. For now I’m on free plan.

I losed a lot of time and effort for working code with 3.x and for now I see that I should rewrite a very big part of code on my side, because previous will be deprecated. I have 6-7 apps which working with backendless.

Why you can’t to add more than 10 objects in one request? You able to count all as separated requests. I know that you guys decide what to do, this is you child. And I think that it’s a good product.
But mBaas should be easy for implementation and for migration between different versions.

Thank you.

Oleg,

Since this is a technical support forum, we do not discuss pricing and licensing questions here. I believe you sent an email yesterday and a representative responded to you. If you have any follow-on questions, please respond back and copy me if you’d like (mark@backendless.com).

As for the question on data paging, there are several reasons why we added paging:

    Retrieving ALL related objects is bad for both backend and the client side. If you have a related table with related 100000 objects, all of them would be returned. This creates a huge payload for the response the client app will simply die with an "out of memory" error. On top of this, the amount of work the backend needs to do and the times it takes for data retrieval is detrimental for the entire service and DOES cause scalability and reliability problems. Our goal for 4.0 was to make the service infinitely more reliable and this is one of the changes we had to introduce. Retrieving all related objects is bad for user experience. Not a single human being can comprehend that much data. The best practice for both mobile and web apps is to provide only that much data that a user needs at that moment. Loading more data in most cases simply is not needed. However, if it is needed, there is API to do just that.
Regards, Mark

Sir, I have a question. Backendless is all free?

You can use Backendless for free, though free version has limits.
Here is a description of Backendless pricing: https://backendless.com/pricing/backendless-cloud-pricing/

@Oleg you can use 100 related objects in one request, won’t that be enough for one request / one screen?

Hi Sergey, thanks for reply.
I have a bunch of apps which has a remote settings and databases, which I want to download in one request and then periodically check for updates. They has a lot of relations.
So implementing of additional code, builders and requests is painfully for me. Because I should lose time for coding and increase timeout and user will wait.

Of course I can do it in parallel requests.
And part of apps can use pagination with related 100 objects, that can be ok for this purposes.

I think that it will be awesome if develober able to define all relations and count of related objects in one request builder.
It’s mean that I want write less code and have more power))

Limiting page size to 100 in Backendless Online was a compromise to allow smooth work of the server and also to nudge the developers a bit to write more user-friendly interfaces. We assumed that 100 objects should be quite enough for any reasonable use-case. Depending on your requirements, I believe you could also workaround the limit by changing the way your data is organized, not only by writing more code to handle it.

The option to increase the page size limit exists in Backendless Pro, though it’s not yet available with the latest version. It may also be enabled in Managed Backendless.

Thank you for the info