webentwicklung-frage-antwort-db.com.de

Android/Firebase - Fehler beim Analysieren des Zeitstempels im GCM-Ereignis - Nullzeitstempel

Ich baue eine Android-App, die Push-Benachrichtigungen erhält. Ich habe Firebase Cloud Messaging eingerichtet und funktioniert ziemlich gut, so dass ich die folgende Payload an ein gültiges Token senden kann und die Benachrichtigung und Daten empfangen werden. 

URL verwenden https://fcm.googleapis.com/fcm/send

{
 "to":"<valid-token>",
 "notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
 "data":{"message":"This is some data"}
}

Meine App empfängt es richtig und kann damit umgehen. 

Die einzige geringfügige Falte ist, dass ich die folgende Ausnahme im Debug werfen kann:

Error while parsing timestamp in GCM event
    Java.lang.NumberFormatException: Invalid int: "null"
        at Java.lang.Integer.invalidInt(Integer.Java:138)
        ...

Die App stürzt nicht ab, sie sieht nur unordentlich aus.

Ich habe versucht, ein timestamp-Element zur Hauptnutzlast, zur Benachrichtigung, zu den Daten und auch zu Variationen wie time hinzuzufügen, kann jedoch die Ausnahme nicht beseitigen (und google, wie ich könnte, finde ich kein Antworten).

Wie muss ich den Zeitstempel übergeben, damit er nicht mehr beschwert?

Bearbeitet: Hier ist meine onMessageReceived-Methode, aber ich denke, die Ausnahme wird ausgelöst, bevor sie hier erscheint

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        //TODO Handle the data
    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }
}

Vielen Dank im Voraus, Chris

16
schofs

Obwohl notification anscheinend ein unterstütztes Element ist (gemäß den Firebase-Web-Docs), war die einzige Möglichkeit, die Ausnahme zu beseitigen, die vollständig zu entfernen und nur den Abschnitt data zu verwenden, und dann in meiner App eine Benachrichtigung zu erstellen als Firebase die Benachrichtigung durchführen zu lassen).

Ich habe diese Website verwendet, um herauszufinden, wie die Benachrichtigungen ausgegeben werden können: https://www.androidhive.info/2012/10/Android-Push-notifications- using-google-cloud-messaging-gcm-php-and-mysql/

Meine Benachrichtigung sieht jetzt folgendermaßen aus: 

    $fields = array("to" => "<valid-token>",
                    "data" => array("data"=>
                                        array(
                                            "message"=>"This is some data",
                                            "title"=>"This is the title",
                                            "is_background"=>false,
                                            "payload"=>array("my-data-item"=>"my-data-value"),
                                            "timestamp"=>date('Y-m-d G:i:s')
                                            )
                                    )
                    );
    ...
    <curl stuff here>
    ...
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

Mein onMessageReceived sieht folgendermaßen aus:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());

        try {
            JSONObject json = new JSONObject(remoteMessage.getData().toString());
            handleDataMessage(json);
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
    }
}

welche handleDataMessage aufruft, die wie folgt aussieht:

private void handleDataMessage(JSONObject json) {
    Log.e(TAG, "Push json: " + json.toString());

    try {
        JSONObject data = json.getJSONObject("data");

        String title = data.getString("title");
        String message = data.getString("message");
        boolean isBackground = data.getBoolean("is_background");
        String timestamp = data.getString("timestamp");
        JSONObject payload = data.getJSONObject("payload");

        // play notification sound
        NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
        notificationUtils.playNotificationSound();

        if (!NotificationUtils.isBackgroundRunning(getApplicationContext())) {
            // app is in foreground, broadcast the Push message
            Intent pushNotification = new Intent(ntcAppManager.Push_NOTIFICATION);
            pushNotification.putExtra("message", message);
            LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);

        } else {
            // app is in background, show the notification in notification tray
            Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
            resultIntent.putExtra("message", message);

            showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
        }
    } catch (JSONException e) {
        Log.e(TAG, "Json Exception: " + e.getMessage());
    } catch (Exception e) {
        Log.e(TAG, "Exception: " + e.getMessage());
    }
}

dieses ruft dann showNotificationMessage

/**
 * Showing notification with text only
 */
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
    notificationUtils = new NotificationUtils(context);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}

Und anschließend notificationUtils.showNotificationMessage

public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
    showNotificationMessage(title, message, timeStamp, intent, null);
}

public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
    // Check for empty Push message
    if (TextUtils.isEmpty(message))
        return;


    // notification icon
    final int icon = R.mipmap.ic_launcher;

    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    final PendingIntent resultPendingIntent =
            PendingIntent.getActivity(
                    mContext,
                    0,
                    intent,
                    PendingIntent.FLAG_CANCEL_CURRENT
            );

    final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            mContext);

    final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_Android_RESOURCE
            + "://" + mContext.getPackageName() + "/raw/notification");


    showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
    playNotificationSound();

}

private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {

    NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

    inboxStyle.addLine(message);

    Notification notification;
    notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
            .setAutoCancel(true)
            .setContentTitle(title)
            .setContentIntent(resultPendingIntent)
            .setSound(alarmSound)
            .setStyle(inboxStyle)
            .setWhen(getTimeMilliSec(timeStamp))
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
            .setContentText(message)
            .build();

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(ntcAppManager.NOTIFICATION_ID, notification);
}

Mehr Details in dem Link oben und es ist eine Menge Handhabung, aber zumindest die Ausnahme ist weg und ich habe die Kontrolle über die Benachrichtigungen.

12
schofs

In meinem Fall war mein Fehler "AndrodManifest.xml"

Ich vermisse einen Dienst (eigentlich fehlt die Erlaubnis für den Firebase-Assistenten von Android Studio :)

original

<service Android:name=".fcm.MyFirebaseInstanceIDService">
        <intent-filter>
            <action Android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
</application>

lösung

    <service Android:name=".fcm.MyFirebaseInstanceIDService">
        <intent-filter>
            <action Android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
    <service Android:name=".fcm.MyFirebaseMessagingService">
        <intent-filter>
            <action Android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
</application>
0
Soo Chun Jung

Ich habe com.google.firebase: firebase-messaging auf 17.3.4 aktualisiert und das Problem ist verschwunden.

0
ms7

Ich war auf den gleichen Fehler gestoßen, der durch das Hinzufügen eines ttl-Werts zur Nutzlast behoben wurde. 

{
   "to":"<valid-token>",
   "notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
   "data":{"message":"This is some data"},
   "ttl": 3600
}
0
jkogara

Ich hatte das gleiche Problem, ich habe gerade "Body" -Parameter in Benachrichtigung und Fehler eingestellt.

0
Andrey Kabylin

ersetzen

 "notification" : {
    "title" : "title !",
    "body" : "body !",
    "sound" : "default"
  },
  "condition" : "'xxx' in topics",
  "priority" : "high",
  "data" : {
....

von (Benachrichtigung entfernen):

{
  "condition" : "'xxxx' in topics",
  "priority" : "high",
  "data" : {
    "title" : "title ! ",
     "body" : "BODY",
 ......
}

Und auf Sie Code: Ersetzen:

 @Override
        public void onMessageReceived(RemoteMessage remoteMessage) { 
           remoteMessage.getNotification().getTitle();
           remoteMessage.getNotification().getBody();

        }

durch

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) { 
       remoteMessage.getData().get("title");
       remoteMessage.getData().get("body");

    }
0
abdessamed

Das folgende Format (keine Benachrichtigungsstelle und keine Arrays) hat die Zeitstempel-Ausnahme für mich behoben:

{
  "to": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
  "data":  {
      "message": "message",
      "title": "hello",
  }
}

Gut getestet mit http://pushtry.com/

Der einzige Grund, warum ich das lange 'eeee ...' eingefügt habe, ist die genaue Größe meines Tokens.

0
Gerry

Was hat bei mir funktioniert:

Aktualisieren, nicht nur firebase-messaging, aber alle Firebase-Bibliotheken bis zur letzten Version. Im Android/app/build.gradle:

dependencies {
    implementation "com.google.firebase:firebase-core:16.0.0"  // upgraded
    implementation "com.google.firebase:firebase-analytics:16.0.0"  // upgraded
    implementation 'com.google.firebase:firebase-messaging:17.3.4'  // upgraded

    // ...

    implementation "com.google.firebase:firebase-invites:16.0.0"  // upgraded

    // ...
}

Nicht alle von ihnen sind in der Version 17.x.

0
ledfusion