web-dev-qa-db-fra.com

Android/Firebase - GCM - Horodatage nul

Je construis une application Android qui recevra les notifications Push. J'ai la configuration de Firebase Cloud Messaging qui fonctionne et qui fonctionne assez bien pour pouvoir envoyer la charge suivante à un jeton valide et recevoir la notification et les données. 

Utilisation de l'URL https://fcm.googleapis.com/fcm/send

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

Mon application le reçoit correctement et peut le gérer. 

La seule légère différence est que l'exception suivante est générée dans le débogage:

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

Il ne bloque pas l'application, il semble simplement désordonné.

J'ai essayé d'ajouter un élément timestamp à la charge utile principale, à la notification, aux données, et j'ai également essayé des variantes telles que time, mais je ne parviens pas à supprimer l'exception (et Google, comme je le pourrais réponse).

Comment puis-je passer l'horodatage afin qu'il cesse de se plaindre?

Edited: Voici ma méthode onMessageReceived, mais je pense que l'exception est levée avant d'arriver ici

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

Merci d'avance, Chris

16
schofs

Même si notification est apparemment un élément pris en charge (selon la documentation Web de Firebase), le seul moyen de supprimer l’exception est de le supprimer entièrement et d’utiliser la section data uniquement, puis de créer une notification (plutôt que que laisser firebase faire la notification).

J'ai utilisé ce site pour déterminer comment générer les notifications: https://www.androidhive.info/2012/10/Android-Push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/

Ma notification ressemble maintenant à ceci: 

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

Ma onMessageReceived ressemble à ceci:

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

qui appelle handleDataMessage qui ressemble à ceci:

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

ceci appelle alors 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);
}

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

Plus de détails dans le lien ci-dessus, et c'est beaucoup de manipulation, mais au moins l'exception a disparu et je contrôle les notifications.

12
schofs

Dans mon cas, mon erreur était "AndrodManifest.xml"

Il me manque un service (en fait, l’assistant Firebase d’Android Studio manque d’autorisation. :))

original

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

solution

    <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

J'ai mis à jour com.google.firebase: firebase-messaging à 17.3.4 et le problème a disparu.

0
ms7

Je rencontrais cette même erreur, j'ai résolu en ajoutant une valeur ttl à la charge utile. 

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

J'ai eu le même problème, je viens de définir le paramètre "body" dans la notification et l'erreur disparaissent.

0
Andrey Kabylin