我现在正在YouTube上建立基于Firebase的聊天。
如果您使用Firebase的FCM收到聊天消息,
在讲座中,使用Retrofit2 将数据作为JSON对象发送到服务器
但是
@Override
public void onMessageReceived (RemoteMessage remoteMessage) {
super.onMessageReceived (remoteMessage);
String sented = remoteMessage.getData (). Get ("sented");
FirebaseUser firebaseUser = FirebaseAuth.getInstance (). GetCurrentUser ();
if (firebaseUser! = null && sented.equals (firebaseUser.getUid ())) {
sendNotification (remoteMessage);
}
}
在这部分 我可以看到发送的消息为空。 所以这似乎是一个错误。
当我阅读YouTube评论时,有很多人遇到相同的问题 似乎没有人知道导致问题的原因。
我不明白为什么sended为null,我想知道remoteMessage如何调用一个名为sended的值
我该如何解决这个问题?
这是我的错误
2019-07-11 19:19:07.488 12281-12457/com.example.blogapp E/AndroidRuntime: FATAL EXCEPTION: Firebase-MyFirebaseMessaging
Process: com.example.blogapp, PID: 12281
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.example.together.notification.MyFirebaseMessaging.onMessageReceived(MyFirebaseMessaging.java:31)
at com.google.firebase.messaging.FirebaseMessagingService.zzc(com.google.firebase:firebase-messaging@@19.0.1:67)
at com.google.firebase.messaging.zzg.run(com.google.firebase:firebase-messaging@@19.0.1:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:6)
at java.lang.Thread.run(Thread.java:764)
这是MyFirebaseMessaging.class
package com.example.together.notification;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import androidx.core.app.NotificationCompat;
import com.example.together.activities.chat.MessageActivity;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessaging extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String sented = remoteMessage.getData().get("sented");
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null && sented.equals(firebaseUser.getUid())){
sendNotification(remoteMessage);
}
}
private void sendNotification(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 j = Integer.parseInt(user.replaceAll("[\\D]",""));
Intent intent = new Intent(this, MessageActivity.class);
Bundle bundle = new Bundle();
bundle.putString("userid", user);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, j, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(Integer.parseInt(icon))
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(defaultSound)
.setContentIntent(pendingIntent);
NotificationManager noti = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int i = 0;
if (j > 0){
i = j;
}
noti.notify(i, builder.build());
}
}
Client.class
package com.example.together.notification;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class Client {
private static Retrofit retrofit = null;
public static Retrofit getClient(String url){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
MyFirebaseIdService.class
package com.example.together.notification;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessagingService;
public class MyFirebaseIdService extends FirebaseMessagingService {
@Override
public void onNewToken(String s) {
super.onNewToken(s);
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
String refreshToken = FirebaseInstanceId.getInstance().getToken();
if (firebaseUser != null){
updateToke(refreshToken);
}
}
private void updateToke(String refreshToken) {
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Tokens");
Token token = new Token(refreshToken);
reference.child(firebaseUser.getUid()).setValue(token);
}
}
这是Data.class
package com.example.together.notification;
public class Data {
private String user;
private int icon;
private String body;
private String title;
private String sented;
public Data(String user, int icon, String body, String title, String sented) {
this.user = user;
this.icon = icon;
this.body = body;
this.title = title;
this.sented = sented;
}
public Data() {
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSented() {
return sented;
}
public void setSented(String sented) {
this.sented = sented;
}
}
这是我的Sender.class
package com.example.together.notification;
public class Sender {
public Data data;
public String to;
public Sender(Data data, String to) {
this.data = data;
this.to = to;
}
}
API服务界面
package com.example.together.fragment;
import com.example.together.notification.MyResponse;
import com.example.together.notification.Sender;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
public interface APIService {
@Headers(
{
"Content-Type:application/json",
"Authorization:key=MyKeyValue"
}
)
@POST("fcm/send")
Call<MyResponse> sendNotification(@Body Sender body);
}
这是我的MessageActivity
package com.example.together.activities.chat;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.together.activities.HomeActivity;
import com.example.together.activities.LoginActivity;
import com.example.together.adapter.MessageAdapter;
import com.example.together.fragment.APIService;
import com.example.together.model.Chat;
import com.example.together.model.User;
import com.example.together.R;
import com.example.together.notification.Client;
import com.example.together.notification.Data;
import com.example.together.notification.MyResponse;
import com.example.together.notification.Sender;
import com.example.together.notification.Token;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MessageActivity extends AppCompatActivity {
private static final String TAG = "MessageActivity";
CircleImageView image_profile;
TextView username;
FirebaseUser fuser;
DatabaseReference reference;
ImageButton btn_send;
EditText text_send;
Intent intent;
MessageAdapter messageAdapter;
List<Chat> mchat;
RecyclerView recyclerView;
ValueEventListener seenListener;
String userid;
APIService apiService;
boolean notify = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MessageActivity.this, LoginActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
});
apiService = Client.getClient("https://fcm.googleapis.com/").create(APIService.class);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
image_profile = findViewById(R.id.image_profile);
username = findViewById(R.id.username);
btn_send = findViewById(R.id.btn_send);
text_send = findViewById(R.id.text_send);
intent = getIntent();
final String userid = intent.getStringExtra("userid");
btn_send.setOnClickListener(v -> {
notify = true;
String msg = text_send.getText().toString();
if (!msg.equals("")){
sendMessage(fuser.getUid(), userid, msg);
}else {
Toast.makeText(MessageActivity.this, "내용을 입력해주세요", Toast.LENGTH_SHORT).show();
}
text_send.setText("");
});
fuser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
username.setText(user.getUsername());
if (user.getImageurl().equals("default")){
image_profile.setImageResource(R.mipmap.ic_launcher);
}else {
Glide.with(getApplicationContext()).load(user.getImageurl()).into(image_profile);
}
readMessages(fuser.getUid(), userid, user.getImageurl());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
seenMessage(userid);
}
private void seenMessage(String userid){
reference = FirebaseDatabase.getInstance().getReference("Chats");
seenListener = reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (chat.getReceiver().equals(fuser.getUid()) && chat.getSender().equals(userid)){
HashMap<String , Object> hashMap = new HashMap<>();
hashMap.put("isseen", true);
snapshot.getRef().updateChildren(hashMap);
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void sendMessage(String sender, String receiver, String message){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
hashMap.put("isseen", false);
reference.child("Chats").push().setValue(hashMap);
final String msg = message;
reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (notify) {
sendNotification(receiver, user.getUsername(), msg);
}
notify = false;
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void sendNotification(String receiver, final String username, final String message){
DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
Query query = tokens.orderByKey().equalTo(receiver);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Token token = snapshot.getValue(Token.class);
Data data = new Data(fuser.getUid(), R.mipmap.ic_launcher, username+": "+message, "새로운 메시지", userid);
Sender sender = new Sender(data, token.getToken());
apiService.sendNotification(sender)
.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response.code() == 200){
if (response.body().success == 1){
Toast.makeText(MessageActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onFailure(Call<MyResponse> call, Throwable t) {
}
});
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void readMessages(final String myid, final String userid, final String imageurl){
mchat = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mchat.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)){
mchat.add(chat);
}
messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
recyclerView.setAdapter(messageAdapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
@Override
protected void onPause(){
super.onPause();
reference.removeEventListener(seenListener);
}
}
我想解决问题的原因
答案 0 :(得分:1)
尝试
@Override
public void onMessageReceived (RemoteMessage remoteMessage) {
super.onMessageReceived (remoteMessage);
}
这个
Map<String, String> data_notify= remoteMessagedata.getNotification().getBody()
或
Map<String, String> data_notify= remoteMessagedata.getData().get("body")
或
Map<String, String> data_notify =remoteMessagedata.getData()