我需要帮助,我开发了一个基于社交的应用程序,该应用程序具有聊天模块,用户可以发送和接收消息,但我无法生成通知。当我发送消息作为响应时,我对凌空错误功能得到"null",下面是我的代码,因为我正在使用 FCM 服务。
private void sendNotification(final String hisId, final String hisName, final String message) {
DatabaseReference allTokens = FirebaseDatabase.getInstance().getReference().child("new").child("Tokens");
Query query = allTokens.orderByKey().equalTo(hisId);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Token token = ds.getValue(Token.class);
//(String user, String body, String title, String sent, Integer icon)
Data data = new Data(myId, hisId + ": " + message, "New Message", hisName, R.drawable.image_icon);
Sender sender = new Sender(data, token.getToken());
try {
JSONObject senderJSONObject = new JSONObject(new Gson().toJson(sender));
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(URL, senderJSONObject,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
//response of the request
Log.i("FCM", "onResponseFCM:" + response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i("FCM", error.getLocalizedMessage() + error.getNetworkTimeMs());
Toast.makeText(ChatActivity.this, "VolleyError: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
// Put params
Map<String, String> header = new HashMap<>();
header.put("content-type", "application/json");
header.put("authorization", "key=myKey");
return header;
}
};
// add this request to queue
requestQueue.add(jsonObjectRequest);
} catch (JSONException e) {
Toast.makeText(ChatActivity.this, "FCM Exception: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
以下是发送消息时收到的日志:
2020-05-25 10:23:52.509 505-1269/com.aadi.developers.asspass E/Volley: [11326] BasicNetwork.performRequest: Unexpected response code 401 for https://fcm.googleapis.com/fcm/send
2020-05-25 10:23:53.311 505-1269/com.aadi.developers.asspass E/Volley: [11326] BasicNetwork.performRequest: Unexpected response code 401 for https://fcm.googleapis.com/fcm/send
2020-05-25 10:23:53.315 505-505/com.aadi.developers.asspass I/FCM: null1901
Firebase 消息传递类是:
public class FirebaseMessaging extensions FirebaseMessagingService {
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
SharedPreferences sp = getSharedPreferences("SP_USER", MODE_PRIVATE);
String savedCurrentUser = sp.getString("Current_USERID", "None");
String sent = remoteMessage.getData().get("sent");
String user = remoteMessage.getData().get("user");
FirebaseUser fUser = FirebaseAuth.getInstance().getCurrentUser();
if (fUser != null && sent.equals(fUser.getUid())) {
if (!savedCurrentUser.equals(user)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
sendOreoAndAboveNotification(remoteMessage);
} else {
sendNormalNotification(remoteMessage);
}
}
}
}
private void sendNormalNotification(RemoteMessage remoteMessage) {
String user = remoteMessage.getData().get("user");
String icon = remoteMessage.getData().get("icon");
String title = remoteMessage.getData().get("title");
String body = remoteMessage.getData().get("body");
RemoteMessage.Notification notification = remoteMessage.getNotification();
int i = Integer.parseInt(user.replaceAll("[\D]", ""));
Intent intent = new Intent(this, ChatActivity.class);
Bundle bundle = new Bundle();
bundle.putString("hisId", user);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pIntent = PendingIntent.getActivity(this, i, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(Integer.parseInt(icon))
.setContentText(body)
.setContentTitle(title)
.setAutoCancel(true)
.setSound(defSoundUri)
.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int j = 0;
if (i > 0) {
j = 1;
}
notificationManager.notify(j, builder.build());
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void sendOreoAndAboveNotification(RemoteMessage remoteMessage) {
String user = "" + remoteMessage.getData().get("user");
String icon = "" + remoteMessage.getData().get("icon");
String title = "" + remoteMessage.getData().get("title");
String body = "" + remoteMessage.getData().get("body");
RemoteMessage.Notification notification = remoteMessage.getNotification();
int i = Integer.parseInt(user.replaceAll("[\D]", ""));
Intent intent = new Intent(this, ChatActivity.class);
Bundle bundle = new Bundle();
bundle.putString("hisId", user);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pIntent = PendingIntent.getActivity(this, i, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
OreoAndOverNotification notification1 = new OreoAndOverNotification(this);
Notification.Builder builder = notification1.getONotifications(title, body, pIntent, defSoundUri, icon);
int j = 0;
if (i > 0) {
j = 1;
}
notification1.getManager().notify(j, builder.build());
}
@Override
public void onNewToken(@NonNull String s) {
super.onNewToken(s);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
updateToken(s);
}
}
private void updateToken(String tokenRefresh) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Tokens");
Token token = new Token(tokenRefresh);
ref.child(user.getUid()).setValue(token);
}
}
好吧,我搜索了很多,并找到了答案,我现在使用字符串而不是JSON对象: 下面的方法解决了我的问题。
public void send(String sendTo, String title, String body) {
Log.i("Check", "Sending: n"+sendTo + "n" + title + "n" + body);
final JSONObject notification = new JSONObject();
JSONObject notificationBody = new JSONObject();
JSONObject data = new JSONObject();
try {
Log.i("Check", "Enter TRY Block");
data.put("key", FCM_KEY);
notificationBody.put("title", title);
notificationBody.put("body", body);
notification.put("to", sendTo);
notification.put("notification", notificationBody);
notification.put("data", data);
} catch (Exception e) {
Log.i("Check", "Enter CATCH Block:" + e.getMessage());
e.printStackTrace();
}
StringRequest req = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i("Check", "Response: " + response);
Toast.makeText(ChatActivity.this, "Response: " + response, Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i("Check", "Error: " + error);
Toast.makeText(ChatActivity.this, "Error: " + error, Toast.LENGTH_LONG).show();
}
}) {
@Override
public byte[] getBody() throws AuthFailureError {
try {
return notification.toString().getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
return null;
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Authorization", "key=" + FCM_KEY);
params.put("Content-Type", "application/json");
return params;
}
};
requestQueue.add(req);
}
**在我的例子中 Puttin "key=" 在FCM_KEY解决我的问题之前。 也可以肯定的是,这是主要问题。如果收到 401 错误。我写成:
params.put("Authorization", FCM_KEY);
但真正的解决方案是:
params.put("Authorization","key=" FCM_KEY);
**
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Authorization", "key=" + FCM_KEY);
params.put("Content-Type", "application/json");
return params;
}
};