PARSE:推送通知“deviceToken”未定义

时间:2015-02-11 08:34:24

标签: android parse-platform push-notification google-cloud-messaging devicetoken

这是Parse Console上我的安装页面中的情况:

enter image description here

如您所见,某些设备具有“deviceToken”,而某些设备没有“deviceToken”。 这不好,因为每个设备都应该有deviceToken才能工作。

这怎么可能?这是一个严重的问题,因为那些没有deviceToken 的人不会收到推送通知!

我已经按照Parse.com上的所有说明进行操作,即使在他们的空白项目的帮助下,也可以在网络上的各种问题的帮助下实现他们所说的一切。但没有什么能解决我的问题,现在我无能为力。

我唯一可以考虑的是,在我的应用程序(它已经在商店中)之前使用 Google Cloud Messaging 然后使用这个新的更新我决定更改系统并使用 Parse 完全删除GCM系统。这两个系统之间是否存在冲突?

我需要解决这个问题,因为您可以想象这是一个严重的错误,现在我的3/4用户都没有收到推送通知。

如果您下载应用程序并安装它:一切都很好,deviceToken就可以了。如果您更新应用程序,因为设备上已存在GCM版本:

  • 某些设备在Parse中注册,没有任何问题
  • 某些设备在Parse中注册但没有 deviceToken

对于没有deviceToken的设备,我尝试过很多东西:手动插入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(在我的情况下是installId)连接到我的userAgent:这工作正常:我总是有installId没有任何问题!这是我在MainActivity中唯一做的事情(我还需要做什么吗?saveInBackground,回调等等。)

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

}

我真的不知道还能做什么,这就是为什么我希望有人可以帮助我。

谢谢。

10 个答案:

答案 0 :(得分:7)

您是否在平板电脑上同时使用2个用户个人资料?因为我有完全相同的问题,根据我的经验,配置文件之间存在冲突。事实上,在我的情况下,一个设备正在向Parse数据库注册2行。一个使用deviceToken,一个使用&#34; undefined&#34; deviceToken。

不幸的是我从来没有解决过这个问题,我想这是Parse的错误。

答案 1 :(得分: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可能有助于调试此问题。

答案 2 :(得分:1)

某些安装确实在deviceToken列中设置了GCM注册ID,这表明您的设置正确无误。安装是否有可能缺少GCM注册ID:

  • 该设备可能无法访问Google服务框架(例如亚马逊Kindle Fire)。如果你已经设置了非GCM ParsePush接收器,那么推送到这些设备仍应该交付。
  • 该应用已从设备中删除,因此已从GCM取消注册。在这种情况下,我们不会自动删除安装,因为这可能会导致意外的数据丢失,因为您可以在安装类中存储任意数据。
  • 当设备尝试注册时,Google Services Framework可能无法使用。

在前两个场景中,这是按预期工作的,并且通常不用担心。

答案 3 :(得分:1)

我一直在努力解决这个问题很长一段时间,直到我最近意识到发生了什么。包名称不仅需要匹配,而且还需要在声明中包含构建风格。

如果您按照解析教程并将com.parse.starter替换为您的软件包名称,那么如果您没有构建风格,则会完成,但如果您这样做,则需要确保将其包括在内:

com.packagename.build_flavor {debug,release等}

答案 4 :(得分:0)

您可以创建一个类并扩展Application以初始化您的应用。这样就可以初始化ParsePushupdateParseInstallation

示例代码:

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

答案 5 :(得分:0)

那些模拟器用户?根据我的经验,如果您在模拟器上运行安装,它不会自动设置设备令牌。

答案 6 :(得分:0)

重命名模块后,我遇到了类似的问题。

尝试清洁项目&#39;然后是“重建项目”

答案 7 :(得分:0)

我遇到了这个问题但在使用phonegap-parse-plugin的cordova应用程序中。我不得不编辑插件中的android java代码来修复,所以实际上是一样的。

尝试在初始化和setDefaultPushCallback之间添加此保存:

ParseInstallation.getCurrentInstallation().save();

必须在他们之间工作。

答案 8 :(得分:0)

我的问题是我在清单中遗漏了这个权限:

<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中的应用程序仪表板。

答案 9 :(得分:0)

我不知道tghis是否可以帮助任何人,但我从包含parse intalation的Application Class中删除此行后,我能够正确获取设备令牌和通知。这是代码。注释行(删除行)使一切正常。任何人都可以解释为什么这有效吗?

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