Intent from notification is not being sent correctly to other Activity

Viewed 53

I'm trying to put an extra into the Intent of the notification in order to open the ChatActivity with the conversation with the user that messaged me. The user that I pass on the NotificationsListener is NOT null. The thing is that I keep getting this error, no matter what other tweaks I try:

2021-04-27 21:46:57.679 13553-13553/com.example.videomeeting E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.videomeeting, PID: 13553
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.videomeeting/com.example.videomeeting.activities.ChatActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.videomeeting.models.User.getUserName()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3431)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7660)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.videomeeting.models.User.getUserName()' on a null object reference
        at com.example.videomeeting.activities.ChatActivity.onCreate(ChatActivity.java:108)
        at android.app.Activity.performCreate(Activity.java:8000)
        at android.app.Activity.performCreate(Activity.java:7984)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7660) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

Here is the code:

NotificationsListener.java

@Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        Intent activityIntent = new Intent(this, ChatActivity.class);
            FirebaseDatabase.getInstance().getReference(KEY_COLLECTION_USERS)
                    .child(remoteMessage.getData().get(KEY_USER_ID))
                    .addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot snapshot) {
                            user = snapshot.getValue(User.class);
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError error) { }
                    });
            activityIntent.putExtra(Constants.INTENT_USER, user);
            activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);
            PendingIntent contentIntent = PendingIntent.getActivity(
                    this,
                    0,
                    activityIntent,
                    FLAG_UPDATE_CURRENT
            );

ChatActivity.java

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

        processExtraData();

        //Toolbar
        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle("");
        setSupportActionBar(toolbar);

        TextView usernameTV = findViewById(R.id.usernameTV);
        usernameTV.setText(remoteUser.getUserName()); //ERROR LINE
@Override
    protected void onResume() {
        super.onResume();
        processExtraData();
    }

    @Override
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        processExtraData();
    }

    private void processExtraData(){
        remoteUser = (User) getIntent().getSerializableExtra(INTENT_USER);
    }

I already checked if the extra from the Intent of the NotificationsListener was empty and it is not. There must be a detail that I'm not seeing. Thanks for your time.

3 Answers

The error message clearly says that remoteUser hasn't been initialized or is null, you need to check what data is being received by the processExtraData() method and

if (User) getIntent().getSerializableExtra(INTENT_USER) doesn't return a user then the problem is in the NotificationsListener class

First, make sure that the user you are passing to the activity is not null. I think onDataChange triggers after you pass user as an extra. I think it might help you and if it doesn't, take a look at this and this.

Thank you guys, I was ONLY tracking the value of the user inside the onDataChange, which is not correct because of its asynchronicity. I made this fix to avoid the null value:

while(!isFound) {
      FirebaseDatabase.getInstance().getReference(KEY_COLLECTION_USERS)
              .child(remoteMessage.getData().get(KEY_USER_ID))
              .addValueEventListener(new ValueEventListener() {
                      @Override
                      public void onDataChange(@NonNull DataSnapshot snapshot) {
                           user = snapshot.getValue(User.class);
                           isFound = true;
                      }

                      @Override
                      public void onCancelled(@NonNull DatabaseError error) {
                      }
             });
}

Thanks again.

Related