プッシュメッセージにFCM
を使用し、すべての着信プッシュ通知をonMessageReceivedで処理しています。今問題は、この関数の内部にあるネストされたjsonの解析にありますremoteMessage.getData()
デバイスでプッシュ通知として次のブロックが来ています。データペイロードの内容はここで変化する可能性があります。後でディーラーになることもできますproductInfo
_{
"to": "/topics/DATA",
"priority": "high",
"data": {
"type": 6,
"dealerInfo": {
"dealerId": "358",
"operationCode": 2
}
}
}
_
これは私がそれをどのように解析しているか
_ if(remoteMessage.getData()!=null){
JSONObject object = null;
try {
object = new JSONObject(remoteMessage.getData());
} catch (JSONException e) {
e.printStackTrace();
}
}
_
remoteMessage.getData()
が_Map<String,String>
_を返すので、今は黒スラッシュでデータを取得しています。
_{
"wasTapped": false,
"dealerInfo": "{\"dealerId\":\"358\",\"operationCode\":2}",
"type": "6"
}
_
そして、私がobject = new JSONObject(remoteMessage.getData().toString());
と書いた場合、次の通知で失敗しました
_{
"to": "regid",
"priority": "high",
"notification" : {
"body": "Message Body",
"title" : "Call Status",
"click_action":"FCM_PLUGIN_ACTIVITY"
},
"data": {
"type": 1,
"callNumber":"ICI17012702",
"callTempId":"0",
"body": "Message Body",
"title" : "Call Status"
}
}
_
エラー私は得ます
_> org.json.JSONException: Unterminated object at character 15 of
> {body=Message Body, type=1, title=Call Status, callNumber=ICI17012702,
> callTempId=0}
_
このコードを試してください:
public void onMessageReceived(RemoteMessage remoteMessage)
{
Log.e("DATA",remoteMessage.getData().toString());
try
{
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
Log.e("JSON OBJECT", object.toString());
String callNumber = object.getString("callNumber");
//rest of the code
}
}
また、JSONが有効であることを確認してください This
GCMからFCMに移行するときにこの問題に直面しました。
以下は私のユースケース(およびOPペイロード)で機能しているため、おそらく他のユーザーでも機能します。
JsonObject jsonObject = new JsonObject(); // com.google.gson.JsonObject
JsonParser jsonParser = new JsonParser(); // com.google.gson.JsonParser
Map<String, String> map = remoteMessage.getData();
String val;
for (String key : map.keySet()) {
val = map.get(key);
try {
jsonObject.add(key, jsonParser.parse(val));
} catch (Exception e) {
jsonObject.addProperty(key, val);
}
}
// Now you can traverse jsonObject, or use to populate a custom object:
// MyObj o = new Gson().fromJson(jsonObject, MyObj.class)
に変わった
JSONObject json = new JSONObject(remoteMessage.getData());
から
JSONObject json = new JSONObject(remoteMessage.getData().toString());
うまくいきます。
dealerInfo
はオブジェクトではなく文字列として解析されるため、文字列を使用して新しいJSONObjectを作成します
JSONObject dealerInfo = new JSONObject(object.getString("dealerInfo"));
String dealerId = dealerInfo.getString("dealerId");
String operationCode = dealerInfo.getString("operationCode");
(moshiを使用して)GSONを追加して機能させたくなかったので、KotlinメソッドでremoteMessageのマップからjson文字列を作成し、1つの例でこれをテストしたので、使用する前にこの実装をテストすることを忘れないでください。
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
super.onMessageReceived(remoteMessage)
var jsonString = "{"
remoteMessage?.data?.let {
val iterator = it.iterator()
while (iterator.hasNext()) {
val mapEntry = iterator.next()
jsonString += "\"${mapEntry.key}\": "
val value = mapEntry.value.replace("\\", "")
if (isValueWithoutQuotes(value)) {
jsonString += value
} else {
jsonString += "\"$value\""
}
if (iterator.hasNext()) {
jsonString += ", "
}
}
}
jsonString += "}"
println(jsonString)
}
private fun isValueWithoutQuotes(value: String):Boolean{
return (value == "true" || value == "false" || value.startsWith("[") || value.startsWith("{") || value == "null" || value.toIntOrNull() != null )
}
編集:
さらに良い方法は、次のようなFCMデータを作成することです。
notificationType: "here is ur notification type"
notificationData: {
//here goes ur data
}
これにより、マップから両方の値を取得できます。
remoteMessage?.data?.let {
it["notificationData"]?.let {
jsonString = it.replace("\\", "")
}
}
遊び回らずにjsonをクリアしました。そして、notificationType
を使用して、jsonを必要なオブジェクトに変換できます(いくつかの通知データ型が時々渡される可能性があるため)
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
// if (/* Check if data needs to be processed by long running job */ true) {
// // For long-running tasks (10 seconds or more) use WorkManager.
// scheduleJob();
// } else {
// // Handle message within 10 seconds
// handleNow();
// }
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
}
}