Android Parse Push- Benachrichtigungsgerät Registrierung nur einmal auf einem Gerät

? Mayur Raval @ | Original: StackOverFlow
---

Jeder Ich bin mit dem Parse -Service für Push-Benachrichtigung in meiner app . aber es registrieren, alle Zeit, als ich neu installieren Sie die App in einem device.Then Problem ist, dass ein Gerät erhalten mehrere Benachrichtigungen auf jedem. Ich habe einige Code für die Registrierung, die unten ist getan. Bitte helfen Sie mir, Dank im Voraus.

Parse.initialize(this, PARSE_APP_ID, PARSE_CLIENT_KEY);
ParseACL defaultACL = new ParseACL();
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
PushService.setDefaultPushCallback(this, MainActivity.class);
ParseInstallation.getCurrentInstallation().getInstallationId();
ParseInstallation.getCurrentInstallation().saveInBackground();

Und zu zeichnen :

PushService.subscribe(this, userName, Detail.class);

In Manifest

Above

  <permission
    android:name="com.example.app.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

  <uses-permission android:name="com.example.app.permission.C2D_MESSAGE" />

In Anwendung tag:

    <receiver android:name="com.parse.ParseBroadcastReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.USER_PRESENT" />
            <action android:name="act" />
        </intent-filter>
    </receiver>

    <receiver android:name="com.app.example.PushReceiver" >

        <intent-filter>
            <action android:name="act" />
            </action>
        </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" />
            <action android:name="act" />
            <category android:name="com.example.app" />
        </intent-filter>
    </receiver>

Und jedes Mal, wenn ich installieren, zeigen Sie sie Fehler, die unten gezeigt wird .

03-10 12:18:48.555: E/ParseCommandCache(12709): Failed to run command.
03-10 12:18:48.555: E/ParseCommandCache(12709): com.parse.ParseException: at least one ID field (installationId,deviceToken) must be specified in this operation
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.ParseCommand$3.then(ParseCommand.java:348)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$10.run(Task.java:452)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeImmediately(Task.java:448)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:322)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:333)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$8.then(Task.java:385)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$8.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11.run(Task.java:485)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeAfterTask(Task.java:481)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$9(Task.java:477)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:350)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.runContinuations(Task.java:514)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$5(Task.java:510)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at   com.parse.Task$TaskCompletionSource.trySetResult(Task.java:569)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.setResult(Task.java:603)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:497)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$10.run(Task.java:452)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeImmediately(Task.java:448)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$8(Task.java:444)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$6.then(Task.java:315)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$6.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.runContinuations(Task.java:514)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$5(Task.java:510)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.trySetResult(Task.java:569)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.setResult(Task.java:603)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:497)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$10.run(Task.java:452)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeImmediately(Task.java:448)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:322)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:333)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11.run(Task.java:489)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeAfterTask(Task.java:481)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$9(Task.java:477)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:350)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.runContinuations(Task.java:514)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$5(Task.java:510)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.trySetResult(Task.java:569)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.setResult(Task.java:603)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$3.run(Task.java:228)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.lang.Thread.run(Thread.java:841)

Ich möchte nur einmal für auf dem Gerät anmelden. es sollte kein Problem sein, wenn App installiert mehrere Zeit in device.please mir helfen, danke im voraus .

In meinem Fall Samsung- Registerkarte 3 -Register zweimal mit gleichen UniqueId . Ist UniqueId als eindeutige Spalte in Parse db gekennzeichnet? Oder wir machen es einzigartig ? wenn ja, wie ?

---

Top 5 Antwort

1Eran @

PushService.subscribe Scheint das Abonnement im lokalen Speicher zwischengespeichert werden, um eine erneute Anmeldung zu vermeiden, wenn Sie die App mehrmals starten.

Dies ist, was der erste Parameter dieser Methode wird verwendet für:

Kontext - Dies wird verwendet, um Zugriff auf lokalen Speicher auf den Cache-   Abonnement, also muss es derzeit             ist eine praktikable Kontext.

( Zitat aus http://parse.com/docs/android/api/com/parse/PushService.html ) .

Allerdings, wenn Sie die App zu deinstallieren, lokalen Speicher für die Anwendung von Ihrem Gerät gelöscht, so dass die neue Anlage wird erneut registrieren zu Google Cloud Messaging verursachen PushService.subscribe . Wenn die neue Registrierung gibt eine neue Registrierungsnummer, würde Parse zwei Anmeldung -IDs, die verwendet werden können, um Push-Benachrichtigungen, um Ihre Anwendung zu senden haben, und beide würden auf die gleiche username Sie versorgt verknüpft werden subscribe . Daher Übermittlung einer Meldung an, dass username wird es für beide Registrierungs IDs zu senden, so dass es zu zweimal kommen .

Wenn Parse senden Sie die Benachrichtigungen für Sie, sollten sie von Google erhalten eine Antwort mit canonical_registration_id, die im Stich lässt sie wissen, eine der Registrierung IDs mit Ihrer Anwendung verbunden auf Ihrem Gerät ist alt, und sollte nicht mehr verwendet werden. Daher (vorausgesetzt Parse eine anständige Umsetzung GCM) das nächste Mal eine Benachrichtigung an Ihr Gerät senden, sollten Sie es nur einmal.

2Mayur Raval @

Ich habe es nach dem Update die Tabelle mit den Sende der eindeutige ID des Android-Gerät.

 String  android_id = Secure.getString(getApplicationContext().getContentResolver(),Secure.ANDROID_ID);         
    Log.e("LOG","android id >>" + android_id);

    PushService.setDefaultPushCallback(this, MainActivity.class);

    ParseInstallation installation = ParseInstallation.getCurrentInstallation();
    installation.put("UniqueId",android_id);

    installation.saveInBackground();

Es wird das rohe zu aktualisieren, aber es muss nicht erneut registrieren Sie das Gerät.

3Sheraz Ahmad Khilji @

Ich war auch dieses Problem vor . Ich Art gelöst durch Aufruf der Methode unten in meiner Tätigkeit onCreate()

/**
     * Initialize Push Messaging Service and subscribe to all-users channel
     */
    private void initParsePushMessaging() {
        ParseInstallation parseInstallation = ParseInstallation
                .getCurrentInstallation();
        //You might skip this if
        if (ParseUser.getCurrentUser() != null) {
            parseInstallation.put("user",
                    ParseUser.getCurrentUser());
        }
        if (parseInstallation.getObjectId() != null)
            parseInstallation.saveInBackground(new SaveCallback() {

                @Override
                public void done(ParseException e) {
                    PushService.subscribe(getApplicationContext(),"channel_name",
                            MainHomeActivity.class);
                }
            });

    }

Auch wenn es nicht ganz mein Problem zu lösen, aber jetzt meine app nicht hängen und nicht mehr die ANR aufgrund dieser Parse Umsetzung. Wenn ich wieder eine App installieren und ausführen jetzt dann die App erstellt ein neues Installationsrekordund entfernen Sie ist die letzte. Das einzige Problem ist, dass die Kanalnamen ist nicht in diesem Lauf, sie aber auf den nächsten Lauf der Kanal haben erfolgreich abonniert .

4user1201239 @

Ich denke, Mukul hat große Wolke Code für diese Ausgabe bereitgestellte

here it is

Parse.Cloud.beforeSave(Parse.Installation, function(request, response) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.Installation);
query.equalTo("owner", request.user);
query.equalTo("uniqueID", request.object.get("uniqueID"));
query.first().then(function(duplicate) {
    if (typeof duplicate === "undefined") {
        console.log("Duplicate does not exist,New installation");
        response.success();
    } else {
        console.log("Duplicate exist..Trying to delete " + duplicate.id);
        duplicate.destroy().then(function(duplicate) {
            console.log("Successfully deleted duplicate");
            response.success();
        }, function() {
            console.log(error.code + " " + error.message);
            response.success();
        });

    }
}, function(error) {
    console.warn(error.code + error.message);
    response.success();
});
});

Beachten Sie, dass Eigentümer ist der Benutzername oder der Primärschlüssel, die Sie denken, u verwenden können.

hier ist der Link des gleichen mit einer besseren Erklärung mukul  https://www.parse.com/questions/check-for-duplicate-installations-of-same-user-on-re-installation-of-app

5Albert Vila @

Was für mich gearbeitet, um diese Ausnahme wurde mit saveEventually() statt saveInBackground() loszuwerden.

Hier haben Sie http://stackoverflow.com/a/27151459/4034572 auf meine Antwort auf eine ähnliche Frage .

Ich denke, dass saveEventually() ist eine bessere Option, da sie gewährleistet, dass die Anlage immer gespeichert werden, unabhängig von der netwwork Verfügbarkeit. Im Gegensatz dazu mit saveInBackground() gibt es eine Chance, dass das Speichern fehlschlägt, da keine Netzwerkverbindung. Auch mit saveEventually() brauchen Sie nicht, um jede Fehlerprüfung, die Sie sollten in einem SaveCallback() mit saveInBackground() zu tun.

In Bezug auf die doppelte Meldungen, sollte dies nicht auf, wenn Sie die neueste Parse SDK ( es nicht, mich mit 1.7.1 geschehen ) werden . Es gab einen Fehler, der nun behoben wurde . Siehe http://stackoverflow.com/q/24590804/4034572 und https://developers.facebook.com/bugs/1520221558200050/ .

Beachten Sie, dass zum ersten Mal der Benutzer erhält eine Benachrichtigung nach der Neuinstallation der App kann diese Benachrichtigung doppelt geliefert werden. Es ist mir passiert, sondern nur geschieht zum ersten Meldung . (Siehe den FB -Link für weitere Details. ) Nach dieser doppelten Benachrichtigung, wird die alte Installation automatisch von Parse entfernt werden. Das ist meine Erfahrung .

Wenn Sie versuchen, das Senden doppelte Meldungen durch die Umsetzung eine gewisse Logik in der CloudCode zu vermeiden sind (unter Verwendung eines before, die beim Speichern eines neuen Installations auslöst, prüfen, ob die App bereits in das Gerät installiert wird, und löschen Sie die alte Installation), tu das nicht dass ! Es ist nicht nötig . Analysiert wird es für Sie tun : Es wird die alte Installation löschen :)