Подтвердить что ты не робот

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')

}

Я не знаю, что еще делать, поэтому я надеюсь, что кто-то может мне помочь в этом.

Спасибо.

4b9b3361

Ответ 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