ParseInstallation.getCurrentInstallation().getObjectId() возвращает null на смартфоне конкретного пользователя

У меня есть приложение для Android, использующее сервер Parse для серверной службы. Несколько пользователей в настоящее время используют мое приложение для Android. Однако некоторые конкретные пользователи столкнулись с проблемой при установке приложения, что объект не создается в таблице установки даже после авторизации.

Когда я взглянул на проблему из своего приложения для Android с некоторым кодом Analytics, я обнаружил, что ParseInstallation.getCurrentInstallation().getObjectId() возвращает null для пользователя, даже если процесс инициализации Parse завершен правильно. С кодом Analytics я проверял метод каждые 10 секунд в течение 10 минут после инициализации Parse, но этот метод всегда возвращал значение null для конкретного пользователя.

// Parse initialization in the onCreate() of Application class
Parse.enableLocalDatastore(this);
Parse.initialize(new Parse.Configuration.Builder(this)
        .applicationId(getString(R.string.parse_app_id))
        .clientKey(getString(R.string.parse_client_key))
        .server(getString(R.string.parse_server_api))
        .build());
ParseUser.enableAutomaticUser();
ParseACL.setDefaultACL(new ParseACL(), true);

// After Log-In, Save the installation.
// (My app user normally would come here 20 ~ 30 seconds or long after the above Parse initialization.) 
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
if (!TextUtils.isEmpty(installation.getObjectId()) { // installation.getObjectId() returns null for the particular user.
    installation.put("GCMSenderId", getString(R.string.fcm_sender_id));
    installation.saveInBackground(
        // will associate the Installation with the User in new SaveCallback()
    );
}

// build.gradle(Module: app)
implementation 'com.github.parse-community.Parse-SDK-Android:parse:1.18.5' 
implementation 'com.github.parse-community.Parse-SDK-Android:fcm:1.18.5'

Большинство пользователей получают действительный ObjectId и работают корректно без каких-либо проблем. Однако, как только пользователь сталкивается с проблемой, объект больше не создается в таблице установки для пользователя, даже если пользователь снова устанавливает приложение.

Я не знаю, является ли это фундаментальной проблемой сервера Parse.

Любой совет мне будет полезен.

Можете ли вы поделиться полным кодом для installation.saveInBackground(...);?

Davi Macêdo 11.07.2019 21:34

@Davi Macêdo installation.saveInBackground(...); не может быть выполнено, потому что installation.getObjectId() возвращает ноль.

Jay 12.07.2019 02:02

Я не понял. Если installation.getObjectId() равно нулю, TextUtils.isEmpty(installation.getObjectId()) истинно, поэтому программа переходит в состояние if и выполняет installation.saveInBackground(...);. Не так ли?

Davi Macêdo 12.07.2019 04:11

@Davi Macêdo Я ошибся в коде. Я изменил приведенный выше пример кода.

Jay 12.07.2019 04:42
0
4
310
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я думаю, что objectId равен нулю, потому что установка по какой-то причине не сохраняется. Я бы рекомендовал вам использовать следующий код и проверить еще раз:

// Parse initialization in the onCreate() of Application class
Parse.enableLocalDatastore(this);
Parse.initialize(new Parse.Configuration.Builder(this)
        .applicationId(getString(R.string.parse_app_id))
        .clientKey(getString(R.string.parse_client_key))
        .server(getString(R.string.parse_server_api))
        .build());
ParseUser.enableAutomaticUser();
ParseACL.setDefaultACL(new ParseACL(), true);

// After Log-In, Save the installation.
// (My app user normally would come here 20 ~ 30 seconds or long after the above Parse initialization.) 
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
if (TextUtils.isEmpty(installation.getObjectId())) { // installation.getObjectId() returns null for the particular user.
    installation.save();
}
installation.put("GCMSenderId", getString(R.string.fcm_sender_id));
installation.saveInBackground(
    // will associate the Installation with the User in new SaveCallback()
);

// build.gradle(Module: app)
implementation 'com.github.parse-community.Parse-SDK-Android:parse:1.18.5' 
implementation 'com.github.parse-community.Parse-SDK-Android:fcm:1.18.5'

Нелегко воспроизвести случай, когда installation.getObjectId() возвращает null на моих смартфонах. Вы уверены, что objectId, deviceToken и tokenType будут иметь допустимое строковое значение в таблице установки после вызова installation.save()?

Jay 12.07.2019 10:27

Должно быть. Есть ли в вашем приложении какой-либо другой фрагмент кода, в котором вы сохраняете установку?

Davi Macêdo 12.07.2019 19:05

@ Davi Macêdo Нет. Я думаю, что метод сохранения должен быть обработан только одним фрагментом кода, потому что повторная копия может вызвать конфликт при сохранении установки.

Jay 13.07.2019 03:08

Я думаю, что вы хорошо с этим кодом. Сделайте несколько тестов и проверьте.

Davi Macêdo 13.07.2019 04:19

Я последовал вашей рекомендации, но нашел конкретного пользователя, который столкнулся с проблемой. Сразу после installation.save()installation.getObjectId() возвращает допустимое строковое значение. Однако, к сожалению, и installation.get("deviceToken"), и installation.get("pushType") по-прежнему возвращали значение null. С помощью кода Analytics я проверял deviceToken и pushType каждые 5 секунд в течение 6 минут после installation.save(), но оба всегда возвращали значение null.

Jay 13.07.2019 15:45

Со своего смартфона я, наконец, нашел основную причину проблемы, заключающуюся в том, что deviceToken и pushType возвращают значение null. Если пользователь телефона активирует энергосбережение в настройках телефона, deviceToken и pushType постоянно возвращают значение null. Что касается проблемы с тем, что getObjectId() возвращает значение null, я все еще смотрю на результаты пользователей моего приложения.

Jay 13.07.2019 17:07

Я оставил результат в другом ответе ниже, потому что комментарий был длиннее.

Jay 26.07.2019 16:47

Вот результаты использования подсказки Дэви Маседо:

После installation.save() иногда installation.get("deviceToken") возвращал значение null. Поэтому я использовал процедуру итерации, чтобы дождаться, пока installation.get("deviceToken") вернет допустимое значение. И тут я позвонил installation.saveInBackground(). В течение 10 дней я наблюдал за результатами пользователей моего приложения, и пока оно работает хорошо.

Если вы используете клиент Parse на устройстве с батарейным питанием, таком как телефон Android, вы столкнетесь с такой же проблемой, как и я. Самым важным моментом является то, что installation.get("deviceToken") чаще возвращает ноль, когда телефон находится в режиме энергосбережения. Поэтому, прежде чем звонить как installation.save(), так и installation.saveInBackground(), вам нужно убедиться, что телефон не находится в режиме энергосбережения и у него хорошее интернет-соединение.

Кстати, с помощью Дави я решил проблему. Спасибо Дави.

Если возникнут дополнительные проблемы, поделюсь с вами.

Другие вопросы по теме