web-dev-qa-db-fra.com

PARSE: Notifications push "deviceToken" non défini

Voici la situation dans ma page d'installation sur Parse Console:

enter image description here

Comme vous le voyez, certains appareils ont le "deviceToken" et certains n'ont pas le "deviceToken". Ce n'est pas une bonne chose car chaque appareil doit avoir le deviceToken pour pouvoir fonctionner. 

Comment est-ce possible? Ceci est un problème sérieux car ceux qui ne possèdent pas deviceToken ne reçoivent pas de notifications Push!

J'ai suivi toutes les instructions sur Parse.com et tout mis en œuvre comme ils l'ont dit, même à l'aide de leur projet vierge et de diverses questions sur le Web. Mais rien n'a résolu mon problème et maintenant je ne peux rien faire.

La seule chose à laquelle je puisse penser, c'est qu'avant que mon application (qui est déjà sur la boutique) utilisait Google Cloud Messaging, puis avec cette nouvelle mise à jour, j'ai décidé de changer de système et d'utiliser Parse retirer complètement le système GCM. Y at-il peut-être un conflit entre les deux systèmes?

J'ai besoin de résoudre ce problème car vous pouvez imaginer qu'il s'agit d'un bug grave et maintenant, 3/4 de mes utilisateurs ne reçoivent pas de notifications Push.

Si vous téléchargez et installez l'application: tout va bien, le deviceToken est ok. Si vous mettez à jour l'application, car il existait déjà une version avec GCM sur l'appareil:

  • certains appareils s'enregistrent dans Parse Good, sans aucun problème
  • certains périphériques s'enregistrent dans Parse mais sans le périphériqueToken

Pour les périphériques qui ne possèdent pas deviceToken, j'ai essayé beaucoup de choses: insérer un deviceToken manuellement, désinstaller et réinstaller l'application, supprimer la ligne spécifique de Parse, etc. Mais rien de bon ... Vous rencontrez toujours ce problème.

MON CODE

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 Dans mon mainActivity, je viens de concaténer le deviceToken (dans mon cas, il s'agit de l'installationId) dans mon userAgent: et cela fonctionne correctement: j'ai toujours l'installationID sans aucun problème! Et c’est la seule chose que je fais dans mon activité principale (dois-je faire autre chose? SaveInBackground, rappel, etc.?)

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

}

Je ne sais pas vraiment quoi faire d'autre, c'est pourquoi j'espère que quelqu'un pourra m'aider avec cela.

Je vous remercie.

21
ernestocattaneo

Utilisez-vous 2 profils d’utilisateur simultanément sur la tablette? Parce que j'ai eu exactement le même problème et d'après mon expérience, il y a un conflit entre les profils. Enfait, dans mon cas, un périphérique enregistrait 2 lignes dans la base de données Parse. L'une avec deviceToken et l'autre avec "undefined" deviceToken.

Malheureusement, je n'ai jamais résolu ce problème, je suppose que c'est un bogue de Parse.

7
WiTHS4UC3

Il pourrait être utile de définir la consignation d’analyse sur verbose pour faciliter le débogage:

Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);

Sur ce, j'ai remarqué que j'utilisais le mauvais "sender_id" dans mon manifeste:

<meta-data Android:name="com.parse.Push.gcm_sender_id"
    Android:value="id:123456789"/>

Ce n'est peut-être pas la solution exacte, mais LOG_LEVEL_VERBOSE pourrait aider à résoudre ce problème.

2
mogile_oli

Cela faisait longtemps que je luttais avec ce problème jusqu'à ce que je réalise récemment ce qui se passait. Non seulement le nom du paquet doit-il correspondre, mais vous devez également inclure la variante de construction dans votre déclaration.

Si vous avez suivi le didacticiel d'analyse et remplacé com.parse.starter par votre nom de package, vous avez terminé si vous n'avez pas de version de construction, mais si vous le faites, vous devez vous assurer de l'inclure en tant que tel:

com.packagename.build_flavor {déboguer, publier, etc.}

1
Paul Hundal

Certaines installations ont un ID d’enregistrement GCM défini dans la colonne deviceToken, ce qui est une bonne indication que votre configuration est correcte. Est-il vraiment possible qu'une installation manque d'un identifiant d'enregistrement GCM:

  • L’appareil peut ne pas avoir accès à Google Services Framework (par exemple, Amazon Kindle Fire). Si vous avez configuré le récepteur ParsePush non-GCM, les envois vers ces périphériques doivent toujours être livrés.
  • L'application a été supprimée de l'appareil et n'a donc pas été enregistrée auprès de GCM. Dans ce cas, nous ne supprimons pas automatiquement les installations car cela pourrait potentiellement entraîner une perte de données inattendue, étant donné que vous êtes autorisé à stocker des données arbitraires dans votre classe d'installation.
  • Il est possible que Google Services Framework ne soit pas disponible lorsque l'appareil a tenté de s'enregistrer.

Dans les deux premiers scénarios, cela fonctionne comme prévu et ne vous inquiétez généralement pas.

1
Héctor Ramos

Je ne sais pas si cela aide quelqu'un, mais j'ai pu obtenir correctement le jeton de périphérique et la notification après avoir supprimé cette ligne de ma classe d'application contenant intalation. voici le code. la ligne commentée (ligne supprimée) a tout fait fonctionner correctement. Quelqu'un peut-il expliquer pourquoi cela fonctionne?

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
0
user3078406

J'ai eu ce problème, mais dans une application Cordova utilisant le plugin phonegap-parse. Je devais éditer le code Java Android dans le plugin pour réparer, donc effectivement la même chose.

Essayez d'ajouter cette sauvegarde entre l'initialisation et le setDefaultPushCallback:

ParseInstallation.getCurrentInstallation().save();

Il faut que ce soit entre eux pour travailler.

0
Andy Ballard

Vous pouvez créer une classe et étendre Application pour initialiser votre application. Tels qui initialisent ParsePush et updateParseInstallation.

Exemple de code:

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();
    }
}

Et puis dans votre 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);
                            }
                       }
          });
0
bjiang

Est-ce que ces utilisateurs de simulateur? D'après mon expérience, si vous exécutez une installation sur votre simulateur, elle ne configure pas automatiquement le jeton de périphérique.

0
Drilem

Mon problème était que je manquais cette permission dans le manifeste:

<uses-permission Android:name="com.google.Android.c2dm.permission.RECEIVE" />

Aussi, je devais ajouter des méta-données juste avant <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" />

Maintenant, vérifiez si vous pouvez obtenir le deviceToken. Consultez également le tableau de bord de votre application dans Parse si tout va bien.

0
L.Kovachev

J'ai eu le même problème après avoir renommé le module.

Essayez 'Clean Project' suivi de 'Rebuild Project'

0
Venkat Kotra