android - PARSE: Notificaciones Push "deviceToken" indefinidas
parse.com push-notification (10)
Esta es la situación en mi página de instalación en la consola de Parse:
Como ve, algunos dispositivos tienen el "deviceToken" y algunos no tienen el "deviceToken". Esto no es bueno porque cada dispositivo debe tener el dispositivo detenido para poder funcionar.
¿Cómo es esto posible? ¡Este es un problema grave porque los que no tienen el dispositivo Retirada no reciben notificaciones automáticas !
He seguido todas las instrucciones en Parse.com y he implementado todo lo que dijeron, incluso con la ayuda de su proyecto en blanco y con la ayuda de varias preguntas en la web. Pero nada solucionó mi problema y ahora no puedo hacer nada.
Lo único que puedo pensar es que antes de que mi aplicación (ya está en la Tienda) solía usar Google Cloud Messaging y luego con esta nueva actualización decidí cambiar el sistema y usar Parse eliminando completamente el sistema GCM. ¿Hay quizás un conflicto entre los dos sistemas?
Necesito arreglar esto ya que puedes imaginar que esto es un error serio y ahora 3/4 de mis usuarios no reciben notificaciones push.
Si descargas la aplicación e la instalas: todo está bien, el dispositivo está bien. Si actualiza la aplicación porque ya había una versión con GCM en el dispositivo:
- algunos dispositivos se registran en Parse bien, sin ningún problema
- algunos dispositivos se registran en Parse pero sin el dispositivoToken
Para los dispositivos que no tienen el dispositivo Detectado he intentado muchas cosas: insertar un dispositivo de forma manual, desinstalar y volver a instalar la aplicación, eliminar la fila específica en Parse, etc. Pero nada bueno ... Todavía estoy enfrentando este problema.
MI CÓDIGO
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 En mi mainActivity simplemente concateno el deviceToken (en mi caso es el ID de instalación) en mi userAgent: y esto funciona bien: ¡siempre tengo el ID de instalación sin ningún problema! Y esto es lo único que estoy haciendo en mi MainActivity (¿tengo que hacer algo más? SaveInBackground, callback, 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'')
}
Realmente no sé qué más hacer, por eso espero que alguien me pueda ayudar con esto.
Gracias.
Puede crear una clase y extender la Application
para inicializar su aplicación. Tales que inicializan ParsePush
y updateParseInstallation
.
Código de muestra:
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();
}
}
Y luego en su 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);
}
}
});
Algunas instalaciones tienen una ID de registro de GCM configurada en su columna deviceToken
, que es una buena indicación de que su configuración es correcta. ¿Es definitivamente posible que una instalación carezca de un Id. De registro de GCM?
- Es posible que el dispositivo no tenga acceso al Marco de servicios de Google (p. Ej., Amazon Kindle Fire). Si ha configurado el receptor que no es de GCM ParsePush, los empujes a estos dispositivos todavía deberían entregarse.
- La aplicación se ha eliminado del dispositivo y, por lo tanto, no se ha registrado desde GCM. En este caso, no eliminamos automáticamente las instalaciones, ya que eso podría ocasionar la pérdida involuntaria de datos, dado que puede almacenar datos arbitrarios en su clase de instalación.
- Es posible que Google Services Framework no esté disponible cuando el dispositivo intentó registrarse.
En los primeros dos escenarios, esto está funcionando como se esperaba y no es algo de lo que preocuparse en general.
¿Son esos usuarios simuladores? Según mi experiencia, si está ejecutando una instalación en su simulador, no configura automáticamente el token del dispositivo.
¿Estás usando 2 perfiles de usuario al mismo tiempo en la tableta? Porque tuve exactamente el mismo problema y, según mi experiencia, hay un conflicto entre los perfiles. De hecho, en mi situación, un dispositivo registraba 2 filas en la base de datos de Parse. Uno con el dispositivo Tomoken y otro con el dispositivo "indefinido".
Desafortunadamente, nunca he resuelto este problema, supongo que esto es un error de Parse.
Tuve un problema similar después del cambio de nombre del módulo.
Pruebe con ''Proyecto limpio'' seguido de ''Reconstruir proyecto''
Tuve este problema pero en una aplicación cordova usando el complemento phonegap-parse-plugin. Tuve que editar el código java de Android en el complemento para arreglarlo, de manera efectiva lo mismo.
Intente agregar esto guardar ENTRE Inicializar y setDefaultPushCallback:
ParseInstallation.getCurrentInstallation().save();
Tiene que ser entre ellos para trabajar.
Había estado luchando con este problema durante mucho tiempo hasta que me di cuenta de lo que estaba pasando. El nombre del paquete no solo debe coincidir, sino que también debe incluir el sabor de la compilación en su declaración.
Si siguió el tutorial de análisis sintáctico y reemplaza com.parse.starter con su nombre de paquete, habrá finalizado si no tiene ningún estilo de compilación, pero si lo hace, debe asegurarse de incluirlo como tal:
com.packagename.build_flavor {debug, release, etc.}
Mi problema fue que me estaba perdiendo este permiso en el manifiesto:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
También tuve que agregar metadatos justo antes de <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" />
Ahora compruebe si puede obtener el dispositivo Retirado. También revise el panel de su aplicación en Parse si todo está bien.
Podría ser útil establecer el registro de parse a verbose para ayudar a depurar aún más:
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
Con eso noté que estaba usando el "sender_id" incorrecto en mi manifiesto:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:123456789"/>
Esa podría no ser la solución exacta, pero LOG_LEVEL_VERBOSE podría ayudar a depurar esto.
No sé si tghis ayuda a alguien, pero pude obtener el token del dispositivo y la notificación correctamente después de eliminar esta línea de mi Clase de aplicación que contiene la integración de parse. aquí está el código. la línea comentada (línea eliminada) hizo que todo funcionara correctamente. ¿Alguien puede explicar por qué esto funciona?
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