У меня есть приложение для 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.
Любой совет мне будет полезен.
@Davi Macêdo installation.saveInBackground(...); не может быть выполнено, потому что installation.getObjectId() возвращает ноль.
Я не понял. Если installation.getObjectId() равно нулю, TextUtils.isEmpty(installation.getObjectId()) истинно, поэтому программа переходит в состояние if и выполняет installation.saveInBackground(...);. Не так ли?
@Davi Macêdo Я ошибся в коде. Я изменил приведенный выше пример кода.
Я думаю, что 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()?
Должно быть. Есть ли в вашем приложении какой-либо другой фрагмент кода, в котором вы сохраняете установку?
@ Davi Macêdo Нет. Я думаю, что метод сохранения должен быть обработан только одним фрагментом кода, потому что повторная копия может вызвать конфликт при сохранении установки.
Я думаю, что вы хорошо с этим кодом. Сделайте несколько тестов и проверьте.
Я последовал вашей рекомендации, но нашел конкретного пользователя, который столкнулся с проблемой. Сразу после installation.save()installation.getObjectId() возвращает допустимое строковое значение. Однако, к сожалению, и installation.get("deviceToken"), и installation.get("pushType") по-прежнему возвращали значение null. С помощью кода Analytics я проверял deviceToken и pushType каждые 5 секунд в течение 6 минут после installation.save(), но оба всегда возвращали значение null.
Со своего смартфона я, наконец, нашел основную причину проблемы, заключающуюся в том, что deviceToken и pushType возвращают значение null. Если пользователь телефона активирует энергосбережение в настройках телефона, deviceToken и pushType постоянно возвращают значение null. Что касается проблемы с тем, что getObjectId() возвращает значение null, я все еще смотрю на результаты пользователей моего приложения.
Я оставил результат в другом ответе ниже, потому что комментарий был длиннее.
Вот результаты использования подсказки Дэви Маседо:
После installation.save() иногда installation.get("deviceToken") возвращал значение null.
Поэтому я использовал процедуру итерации, чтобы дождаться, пока installation.get("deviceToken") вернет допустимое значение. И тут я позвонил installation.saveInBackground().
В течение 10 дней я наблюдал за результатами пользователей моего приложения, и пока оно работает хорошо.
Если вы используете клиент Parse на устройстве с батарейным питанием, таком как телефон Android, вы столкнетесь с такой же проблемой, как и я.
Самым важным моментом является то, что installation.get("deviceToken") чаще возвращает ноль, когда телефон находится в режиме энергосбережения.
Поэтому, прежде чем звонить как installation.save(), так и installation.saveInBackground(), вам нужно убедиться, что телефон не находится в режиме энергосбережения и у него хорошее интернет-соединение.
Кстати, с помощью Дави я решил проблему. Спасибо Дави.
Если возникнут дополнительные проблемы, поделюсь с вами.
Можете ли вы поделиться полным кодом для
installation.saveInBackground(...);?