PARSE: Push-уведомления "deviceToken" undefined
Это ситуация на моей странице установки на консоли анализа:
![enter image description here]()
Как вы видите, некоторые устройства имеют "deviceToken", а некоторые не имеют "deviceToken". Это не хорошо, потому что для каждого устройства должно быть устройствоToken для работы.
Как это возможно? Это серьезная проблема, потому что те, у кого нет устройстваToken , не получают push-уведомления!
Я следил за всеми инструкциями на Parse.com и реализовал все, как они сказали, даже с помощью своего пустого проекта и с помощью различных вопросов в Интернете. Но ничего не исправила мою проблему, и теперь я ничего не могу сделать.
Единственное, о чем я могу думать, это то, что перед тем, как мое приложение (уже в Магазине) использовало Облачные сообщения Google, а затем с этим новым обновлением, я решил изменить систему и используйте Parse, полностью удалив систему GCM. Возможно, существует конфликт между двумя системами?
Мне нужно исправить это, так как вы можете себе представить, что это серьезная ошибка, и теперь 3/4 моих пользователей не получают push-уведомлений.
Если вы загрузите приложение и установите его: все хорошо, deviceToken в порядке. Если вы обновите приложение, потому что на нем уже была версия с GCM:
- некоторые устройства регистрируются в Parse хорошо, без каких-либо проблем
- некоторые устройства регистрируются в Parse, но без deviceToken
Для устройств, у которых нет устройства Token, я пробовал много вещей: вставлять deviceToken вручную, удалять и переустанавливать приложение, удалять определенную строку в Parse и т.д. Но ничего хорошего... Все еще смотря на это проблема.
МОЙ КОД
Application.java
public class Application extends android.app.Application {
public Application() {
}
@Override
public void onCreate() {
super.onCreate();
// Initialize the Parse SDK.
Parse.initialize(this, "x", "x");
// Specify an Activity to handle all pushes by default.
PushService.setDefaultPushCallback(this, MainActivity.class);
}
}
MainActivity.java
В моей mainActivity я просто конкатенирую deviceToken (в моем случае это installationId) в моем userAgent: и эта работа прекрасна: у меня всегда есть инсталляция без проблем! И это единственное, что я делаю в своей MainActivity (нужно ли мне что-то делать? SaveInBackground, callback и т.д.?)
deviceToken = ParseInstallation.getCurrentInstallation().getInstallationId();
webSettings.setUserAgentString(userAgent + " ||" + deviceToken);
AndroidManifest.xml
<!-- Gestione del guasto-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Utilizzo di internet -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permesso di vibrare per le push notifications -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Mantiene attivo il processore così da poter ricevere in qualsiasi momento le notifiche -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Consente di impostare l'allarme per l'aggiornamento automatico -->
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<permission android:name="com.hoxell.hoxellbrowser.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.hoxell.hoxellbrowser.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:name="com.hoxell.hoxellbrowser.Application"
android:allowBackup="true"
android:icon="@drawable/ic_launcher_hoxell"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
<!-- Richiesto per le applicazioni che usano Google Play Services -->
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"></activity>
<receiver android:name=".AlarmReceiver"/>
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.hoxell.hoxellbrowser.Receiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.hoxell.hoxellbrowser" />
</intent-filter>
</receiver>
</application>
build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// You must install or update the Support Repository through the SDK manager to use this dependency.
compile 'com.android.support:support-v4:20.+' //support
compile "com.google.android.gms:play-services:5.0.+" //play services
compile 'com.parse.bolts:bolts-android:1.+'
compile fileTree(dir: 'libs', include: 'Parse-*.jar')
}
Я не знаю, что еще делать, поэтому я надеюсь, что кто-то может мне помочь в этом.
Спасибо.
Ответы
Ответ 1
Используете ли вы два пользовательских профиля одновременно на планшете? Потому что у меня была точно такая же проблема, и из моего опыта возникает конфликт между профилями. Infact, в моей ситуации одно устройство регистрировало 2 строки в базе данных Parse. Один с устройствомToken и один с "undefined" deviceToken.
К сожалению, я никогда не решал эту проблему, я думаю, это ошибка в Parse.
Ответ 2
Может быть полезно настроить ведение журнала разбора на подробные, чтобы помочь отладить дальнейшее:
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
С этим я заметил, что я использовал неправильный "sender_id" в своем манифесте:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:123456789"/>
Это может быть не точное решение, но LOG_LEVEL_VERBOSE может помочь отладить это.
Ответ 3
Некоторые установки имеют идентификатор регистрации GCM, установленный в столбце deviceToken
, что является хорошим показателем правильности вашей установки. Возможно ли, чтобы установка не имела идентификатора регистрации GCM:
- Устройство может не иметь доступа к Google Services Framework (например, Amazon Kindle Fire). Если вы настроили приемник ParsePush без GCM, нажатие на эти устройства должно быть доставлено.
- Приложение было удалено с устройства и, следовательно, оно не было зарегистрировано в GCM. В этом случае мы автоматически не удаляем установки, поскольку это может привести к непредвиденной потере данных, учитывая, что вы можете хранить произвольные данные в своем классе установки.
- Служба Google Services Framework может быть недоступна, когда устройство попыталось зарегистрировать себя.
В первых двух сценариях это работает так, как ожидалось, и об этом вообще не о чем беспокоиться.
Ответ 4
Я долгое время боролся с этой проблемой, пока я недавно не понял, что происходит. Мало того, что имя пакета должно соответствовать, но вам также необходимо включить в свою декларацию компоновку сборки.
Если вы выполнили руководство по синтаксическому разбору и заменили com.parse.starter своим именем пакета, вы закончите, если у вас нет стиля сборки, но если вам нужно, обязательно включите его как таковое:
com.packagename.build_flavor {debug, release и т.д.}
Ответ 5
Вы можете создать класс и расширить Application
для инициализации своего приложения. Такие, которые инициализируют ParsePush
и updateParseInstallation
.
Пример кода:
public class YourappApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Parse.initialize(this,YOU_PARSE_applicationId, YOU_PARSE_clientKey);
ParseInstallation.getCurrentInstallation().saveInBackground();
ParsePush.subscribeInBackground("", new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
}
public static void updateParseInstallation(ParseUser user) {
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.put("userId", user.getObjectId());
installation.saveInBackground();
}
}
И затем в вашем LoginActivity: updateParseInstallation
ParseUser.logInInBackground(username, password, new LogInCallback() {
@Override
public void done(ParseUser parseUser, ParseException e) {
setProgressBarIndeterminateVisibility(false);
if(e == null){
YourappApplication.updateParseInstallation(parseUser);
Intent intent = new Intent(LoginActivity.this,
MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
Ответ 6
Являются ли эти симуляторы пользователями? По моему опыту, если вы используете установку на своем симуляторе, она не настраивает токен устройства.
Ответ 7
У меня была аналогичная проблема после переименования модуля.
Попробуйте "Очистить проект", а затем "Восстановить проект"
Ответ 8
У меня была эта проблема, но в приложении cordova, использующем плагин phonegap-parse. Мне нужно было отредактировать javas-код андроида в плагине, чтобы исправить, так эффектно то же самое.
Попробуйте добавить это сохранение BETWEEN Инициализировать и setDefaultPushCallback:
ParseInstallation.getCurrentInstallation().save();
Он должен быть между ними, чтобы работать.
Ответ 9
Моя проблема заключалась в том, что я пропустил это разрешение в манифесте:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Также мне пришлось добавить метаданные непосредственно перед
<service android:name="com.parse.PushService" />
:
<meta-data
android:name="com.parse.APPLICATION_ID"
android:value="YourParseApplicationID" />
<meta-data
android:name="com.parse.CLIENT_KEY"
android:value="YourParseClientKey" />
Теперь проверьте, можете ли вы получить deviceToken. Также проверьте панель инструментов приложения в Parse, если все в порядке.
Ответ 10
Я не знаю, помогает ли tghis кому-либо, но я смог правильно получить токен устройства и уведомление после удаления этой строки из моего класса приложения, содержащего синтаксический анализ. вот код. прокомментированная строка (удаленная строка) заставила все работать исправно. Может ли кто-нибудь объяснить, почему это работает?
package com.test.android.push;
import android.app.Application;
import com.parse.Parse;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
public class FarrApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "xxxx", "xxxx");
ParseInstallation.getCurrentInstallation().saveInBackground();
ParsePush.subscribeInBackground("---"); // REMOVED AND WORKS