简体   繁体   中英

Push notification is sent to the user that sends the message and not to the receiver

I have create a method for sending notifications to other users if they send you a message. The issue that I am currently having is that the user that sends the message is the one that receives the notification. Obviously I want the other user, the user that the notification is for to receive it.

So I am testing this out on my emulator and actual device, and when I send the notification I receive the notification and then when I look at the message with the other device I get another notification sent to that same device.

So essentially I am getting two notifications both sent to the same device that sent the message. How do I fix it so that only the user that the notification is for receives it, and no one else, and I don't receive it either?

I have been trying to change my if statement , I think that's the key here, but haven't been able to figure it out. Suggestions?

In my sendNotification(); method I have the line if(mFirebaseUser.getUid.equals(receiver)) {...} so shouldn't that make it show up on the device who the notification is for?

MessageActivity

public class MessageActivity extends AppCompatActivity {

    TextView mUsername;
    TextView mButtonSend;
    EditText mTextSend;

    FirebaseUser mFirebaseUser;
    DatabaseReference mReference;

    MessageAdapter mMessageAdapter;
    List<Chat> mChat;
    RecyclerView mRecyclerView;

    String mId;
    String mMessageId;
    String mUserId;

    String NOTIFICATION_CHANNEL_ID = "e.events.Notifications.test";
    String NOTIFICATION_CHANNEL_NAME = "Events";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);

        mId = getIntent().getStringExtra("id");
        mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        mUserId = getIntent().getStringExtra("userid");

        mButtonSend.setOnClickListener(v -> {
            String message = mTextSend.getText().toString();
            if (!message.equals("")) {
                sendMessage(mFirebaseUser.getUid(), mId, message);
                sendNotification();
            } else {
                Toast.makeText(MessageActivity.this, "Write something", Toast.LENGTH_SHORT).show();
            }
            mTextSend.setText("");
        });

        getUserInfo();
        seenMessage(mId);
    }

    private void sendNotification() {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats").child(mMessageId);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    String receiver = dataSnapshot.child("receiver").getValue(String.class);
                    if (mFirebaseUser.getUId().equals(receiver)) {
                            showNotification();
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

    private void showNotification() {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats").child(mMessageId);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    String message = dataSnapshot.child("message").getValue(String.class);

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);

                        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                        notificationManager.createNotificationChannel(notificationChannel);

                        NotificationCompat.Builder builder = new NotificationCompat.Builder(MessageActivity.this, NOTIFICATION_CHANNEL_ID)
                                .setContentTitle("Events")
                                .setContentText(message)
                                .setSmallIcon(R.mipmap.ic_launcher)
                                .setAutoCancel(true);

                        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MessageActivity.this);
                        notificationManagerCompat.notify(999, builder.build());
                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

    private void sendMessage(String sender, final String receiver, String message) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");

        Date date = Calendar.getInstance().getTime();
        String formattedDate = DateFormat.getDateInstance(DateFormat.FULL).format(date);

        String time = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            time = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
        }

        mMessageId = reference.push().getKey();

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("sender", sender);
        hashMap.put("receiver", receiver);
        hashMap.put("message", message);
        hashMap.put("isseen", false);
        hashMap.put("date", formattedDate);
        hashMap.put("time", time);
        hashMap.put("timestamp", ServerValue.TIMESTAMP);
        hashMap.put("messageId", mMessageId);

        reference.child(mMessageId).setValue(hashMap);

        final DatabaseReference chatReference = FirebaseDatabase.getInstance().getReference("Chatlist").child(mFirebaseUser.getUid()).child(mId);
        chatReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (!dataSnapshot.exists()) {
                    chatReference.child("receiver").setValue(mId);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        final DatabaseReference chatReferenceReceiver = FirebaseDatabase.getInstance().getReference("Chatlist").child(mId).child(mFirebaseUser.getUid());
        chatReferenceReceiver.child("receiver").setValue(mFirebaseUser.getUid());
    }

    private void readMessages(final String myid, final String userid, final String imageurl) {
        mChat = new ArrayList<>();
        mReference = FirebaseDatabase.getInstance().getReference("Chats");
        mReference.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 != null) {
                        if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) || chat.getReceiver().equals(userid) && chat.getSender().equals(myid)) {
                            mChat.add(chat);
                        }
                    }

                    mMessageAdapter = new MessageAdapter(MessageActivity.this, mChat, imageurl);
                    mRecyclerView.setAdapter(mMessageAdapter);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

Your sendNotification() method looks redundant.

As far as I can understand, below is the flow you expect:

  1. User A clicks send button mButtonSend
  2. Click action triggers sendMessage(...) which writes the chat message to firestore

  3. User B has a listener set up to the chats collection so whenever a new chat is written in firestore, listener receives an event

  4. When that listener receives an event, it does two things- it queues a notification by calling showNotification(), and it pushes the received chat in adapter.

Now, there are several issues with your code above:

  1. You are setting up several unnecessary listeners. You should set up just one listener on chat collection that receives event. Currently, you have listeners set up inside sendNotification , showNotification , sendMessage and readMessages methods.

  2. In mButtonSend click listener, you are calling both sendMessage and sendNotification methods. Instead you should just call sendMessage method to write to firestore. You can remove the sendNotification call as well as the method implementation itself

  3. Once you refactor your code to have just one listener, you can call showNotifcation method inside that listener event. There are still some tricks that you would need to implement to avoid both users receiving the notification. For example= when a new event is received in chat collection listener, you can check who the author of the message is. If the current user id == author id then don't show notification, otherwise do.

  4. As per your current design- If the receiver user does not have the app and the activity open, he won't receive the notification as the listener only exists as long as the activity is there. If you want to be able to send notifications even when the user does not have the app open- you need to use FCM or any other push messaging mechanism.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM