onyxbits / raccoon4

APK Downloader for Google Play
https://raccoon.onyxbits.de
Apache License 2.0
644 stars 90 forks source link

downloadAuthCookie is sometimes empty #81

Closed paulo-raca closed 4 years ago

paulo-raca commented 4 years ago

I'm seeing this error pop up intermitently:

Caused by: java.lang.IndexOutOfBoundsException: Index: 0
    at java.util.Collections$EmptyList.get(Collections.java:4454)
    at com.akdeniz.googleplaycrawler.GooglePlay$AndroidAppDeliveryData.getDownloadAuthCookie(GooglePlay.java:5981)
    at com.akdeniz.googleplaycrawler.DownloadData.<init>(DownloadData.java:35)
    at com.akdeniz.googleplaycrawler.GooglePlayAPI.delivery(GooglePlayAPI.java:473)
        ...

Any ideas?

Thank you!

onyxbits commented 4 years ago

Is this an app specific, persistent problem?

paulo-raca commented 4 years ago

I've seen it happen with multiple apps, but the problem isn't persistent -- Something like 10% of the time

onyxbits commented 4 years ago

Any way to reproduce this?

paulo-raca commented 4 years ago

Thanks for looking.

I have reduced my reproduction code to this:

    @RepeatedTest(100)
    public void test() throws Throwable {
        GooglePlayAPI api = new GooglePlayAPI(GOOGLE_ACCOUNT, GOOGLE_PASSWORD, null);
        api.login();
        api.checkin();
        System.out.println(api + ", " + api.getAndroidID() + " " + api.getToken());

        String packageName = "com.android.chrome";

        GooglePlay.DocV2 appDetails = api.details(packageName).getDocV2();
        int offerType = appDetails.getOffer(0).getOfferType();
        boolean paid = appDetails.getOffer(0).getCheckoutFlowRequired();

        DownloadData downloadData;
        int versionCode = appDetails.getDetails().getAppDetails().getVersionCode();
        if (paid) {
            downloadData = api.delivery(packageName, versionCode, offerType);
            System.out.println("api.delivery succeeded: " + downloadData);
        } else {
            try {
                downloadData = api.purchaseAndDeliver(packageName, versionCode, offerType);
                System.out.println("api.purchaseAndDeliver succeeded: " + downloadData);

            } catch (GooglePlayException e) {
                System.out.println("purchaseAndDeliver failed");
                e.printStackTrace();

                // FIXME: Sometimes api.purchaseAndDeliver fails with "GooglePlayException: Your device is not compatible with this item."
                // However api.delivery() works without problems
                downloadData = api.delivery(packageName, versionCode, offerType);
                System.out.println("api.delivery succeeded: " + downloadData);
            }
        }
    }

It only fails once in a while (Therefore the @RepeatedTest()).

onyxbits commented 4 years ago

Don't call api.checkin() repeatedly. That's how you register a new GSF ID for a new device. Play needs a second or two for the ID to settle, so that's probably why it fails sometimes.

paulo-raca commented 4 years ago

This is a much simplified code, on the real thing I register as lots of distinct devices (Varying the model, abi, sdk, etc) and download all variations of each app.

However, yes, I could make registration into a separate step and reuse the GSF ids. I'll try that.

Thank you!

paulo-raca commented 4 years ago

The issue is gone now

I merged latest changes to Raccoon, but I have no idea if the fix came from your updates or from Google's servers ¯\(ツ)

Thank you

onyxbits commented 4 years ago

The latest patch didn't touch any relevant parts.