Bertho Joris
Bertho Joris

Reputation: 1601

Firebase : App crash when notification comes with app not opened

I follow this tutorial Lapit Chat App - Push Notifications - Firebase Tutorials - Part 24

All went well, it's just that I found a bit of a problem when the notifications came and my device was not running the application (background mode), and when I clicked on the notification panel, my app became crashed.

The error does not occur if my device has previously opened the application. When I click on the notification panel, the application runs normally and opens my ProfileActivity

I get ErrorLog for this error

07-29 16:36:54.512 16573-16573/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.bertho.chat, PID: 16573
                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bertho.chat/com.bertho.chat.ProfileActivity}: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2464)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
                                                       at android.app.ActivityThread.access$900(ActivityThread.java:154)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1391)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:234)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5526)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                       at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
                                                    Caused by: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
                                                       at com.google.firebase.database.DatabaseReference.child(Unknown Source)
                                                       at com.bertho.chat.ProfileActivity.onCreate(ProfileActivity.java:56)
                                                       at android.app.Activity.performCreate(Activity.java:6285)
                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524) 
                                                       at android.app.ActivityThread.access$900(ActivityThread.java:154) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1391) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:234) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:5526) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                                                       at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102) 

This is my ProfileActivity.java

public class ProfileActivity extends BaseActivity {

    private ImageView mProfileImage;
    private TextView mProfileName, mProfileStatus, mProfileFriendsCount;
    private Toolbar mToolbar;
    private Button mProfileSendReqBtn, mProfileDeclineReqBtn;
    private ProgressDialog mDialog;

    private FirebaseUser mCuurentUser;

    private String mCuurent_state;

    private DatabaseReference mUserDatabase, mFriendsReqDatabase, mFriendsDatabase, mNotificationDatabase;

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

        final String user_id = getIntent().getStringExtra( "user_id" );

        mDialog = new ProgressDialog( this );

        mUserDatabase = FirebaseDatabase.getInstance().getReference().child( "Users" ).child( user_id );
        mUserDatabase.keepSynced( true );

        mFriendsReqDatabase = FirebaseDatabase.getInstance().getReference().child( "FriendsRequest" );
        mFriendsReqDatabase.keepSynced( true );

        mFriendsDatabase = FirebaseDatabase.getInstance().getReference().child( "FriendsData" );
        mFriendsDatabase.keepSynced( true );

        mNotificationDatabase = FirebaseDatabase.getInstance().getReference().child( "Notifications" );

        mProfileImage = (ImageView) findViewById( R.id.profile_image );
        mProfileName = (TextView) findViewById( R.id.profile_displayName );
        mProfileStatus = (TextView) findViewById( R.id.profile_status );
        mProfileFriendsCount = (TextView) findViewById( R.id.profile_totalFriends );
        mProfileSendReqBtn = (Button) findViewById( R.id.profile_send_fr_btn );
        mProfileDeclineReqBtn = (Button) findViewById( R.id.profile_decline_req_btn );

        mCuurentUser = FirebaseAuth.getInstance().getCurrentUser();

        showLoading( "Load Profile Data" );

        mCuurent_state = "not_friends";

        mUserDatabase.addValueEventListener( new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String display_name = dataSnapshot.child( "name" ).getValue().toString();
                String display_status = dataSnapshot.child( "status" ).getValue().toString();
                final String display_image = dataSnapshot.child( "image" ).getValue().toString();

                mProfileName.setText( display_name );
                mProfileStatus.setText( display_status );

                if (mCuurent_state == "not_friends") {
                    mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                    mProfileDeclineReqBtn.setEnabled( false );
                } else if (mCuurent_state == "received") {
                    mProfileDeclineReqBtn.setVisibility( View.VISIBLE );
                    mProfileDeclineReqBtn.setEnabled( true );
                } else {
                    mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                    mProfileDeclineReqBtn.setEnabled( false );
                }


                /*Picasso.with( ProfileActivity.this )
                        .load( display_image )
                        .placeholder( R.drawable.no_profile )
                        .into( mProfileImage );*/

                Picasso.with( ProfileActivity.this )
                        .load( display_image )
                        .networkPolicy( NetworkPolicy.OFFLINE )
                        .placeholder( R.drawable.no_profile )
                        .into( mProfileImage, new Callback() {
                            @Override
                            public void onSuccess() {

                            }

                            @Override
                            public void onError() {
                                Picasso.with( ProfileActivity.this )
                                        .load( display_image )
                                        .placeholder( R.drawable.no_profile )
                                        .into( mProfileImage );
                            }
                        } );


                // ========== FRIEND LIST ONLY FOR CURRENT USER LOGGED IN ==========
                mFriendsReqDatabase.child( mCuurentUser.getUid() ).addListenerForSingleValueEvent( new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (dataSnapshot.hasChild( user_id )) {
                            String req_type = dataSnapshot.child( user_id ).child( "request_type" ).getValue().toString();
                            if (req_type.equals( "received" )) {
                                mCuurent_state = "req_received";
                                mProfileSendReqBtn.setText( "Accept Friend Request" );

                                mProfileDeclineReqBtn.setVisibility( View.VISIBLE );
                                mProfileDeclineReqBtn.setEnabled( true );

                            } else if (req_type.equals( "sent" )) {
                                mCuurent_state = "req_sent";
                                mProfileSendReqBtn.setText( "Cancel Friend Request" );
                                mProfileSendReqBtn.setBackgroundColor( getResources().getColor( R.color.colorAccent ) );

                                mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                                mProfileDeclineReqBtn.setEnabled( false );

                            }

                        } else {

                            /*Toast.makeText(getApplicationContext(), "TIDAK ADA : " + mCuurent_state, Toast.LENGTH_SHORT).show();*/

                            mFriendsDatabase.child( mCuurentUser.getUid() ).addListenerForSingleValueEvent( new ValueEventListener() {
                                @Override
                                public void onDataChange(DataSnapshot dataSnapshot) {
                                    if (dataSnapshot.hasChild( user_id )) {
                                        mCuurent_state = "friends";
                                        mProfileSendReqBtn.setText( "Unfriend This Person" );
                                        /*mProfileSendReqBtn.setEnabled( false );
                                        mProfileSendReqBtn.setBackgroundColor( getResources().getColor( R.color.colorAccent ) );*/

                                        mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                                        mProfileDeclineReqBtn.setEnabled( false );
                                    }
                                }

                                @Override
                                public void onCancelled(DatabaseError databaseError) {

                                }
                            } );

                        }
                        mDialog.dismiss();
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                } );
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        } );

        mProfileSendReqBtn.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // ========== ADD FRIEND REQUEST ==========
                if (mCuurent_state.equals( "not_friends" )) {

                    showLoading( "Data is processing...!" );
                    mProfileSendReqBtn.setEnabled( false );

                    mFriendsReqDatabase.child( mCuurentUser.getUid() ).child( user_id ).child( "request_type" ).setValue( "sent" ).addOnCompleteListener( new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                mFriendsReqDatabase.child( user_id ).child( mCuurentUser.getUid() ).child( "request_type" ).setValue( "received" ).addOnCompleteListener( new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        if (task.isSuccessful()) {

                                            HashMap<String, String> notificationData = new HashMap<>(  );
                                            notificationData.put( "from", mCuurentUser.getUid() );
                                            notificationData.put( "type", "request" );

                                            mNotificationDatabase.child( user_id ).push().setValue( notificationData ).addOnSuccessListener( new OnSuccessListener<Void>() {
                                                @Override
                                                public void onSuccess(Void aVoid) {
                                                    mDialog.dismiss();
                                                    mCuurent_state = "req_sent";
                                                    mProfileSendReqBtn.setText( "Cancel Friend Request" );
                                                    mProfileSendReqBtn.setBackgroundColor( getResources().getColor( R.color.colorAccent ) );

                                                    mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                                                    mProfileDeclineReqBtn.setEnabled( false );

                                                    showSuccess( "Request Sent!" );
                                                }
                                            } );


                                        } else {
                                            mDialog.dismiss();
                                            onError( "Request Submission Failed!" );
                                        }
                                    }
                                } );
                            } else {
                                mDialog.dismiss();
                                onError( "Request Submission Failed!" );
                            }
                            mProfileSendReqBtn.setEnabled( true );
                        }
                    } );
                }


                // ========== CANCEL REQUEST FRIEND ==========
                if (mCuurent_state.equals( "req_sent" )) {

                    showLoading( "Data is processing...!" );
                    mProfileSendReqBtn.setEnabled( false );

                    mFriendsReqDatabase.child( mCuurentUser.getUid() ).child( user_id ).removeValue().addOnCompleteListener( new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                mFriendsReqDatabase.child( user_id ).child( mCuurentUser.getUid() ).removeValue().addOnCompleteListener( new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        if (task.isSuccessful()) {
                                            mDialog.dismiss();
                                            mCuurent_state = "not_friends";
                                            mProfileSendReqBtn.setText( "Send Friend Request" );
                                            mProfileSendReqBtn.setBackgroundColor( getResources().getColor( R.color.successAlert ) );

                                            mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                                            mProfileDeclineReqBtn.setEnabled( false );

                                            onSuccess( "Cancel Request Success!" );
                                        } else {
                                            mDialog.dismiss();
                                            onError( "Cancel Request Failed!" );
                                        }
                                    }
                                } );
                            } else {
                                mDialog.dismiss();
                                onError( "Cancel Request Failed!" );
                            }
                            mProfileSendReqBtn.setEnabled( true );
                        }
                    } );
                }


                // ========== ACTION APPROVE REQUEST ==========
                if (mCuurent_state.equals( "req_received" )) {


                    showLoading( "Data is processing...!" );
                    mProfileSendReqBtn.setEnabled( false );

                    final String currentDate = DateFormat.getDateTimeInstance().format( new Date() );

                    mFriendsDatabase.child( mCuurentUser.getUid() ).child( user_id ).setValue( currentDate ).addOnCompleteListener( new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                mFriendsDatabase.child( user_id ).child( mCuurentUser.getUid() ).setValue( currentDate ).addOnSuccessListener( new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void aVoid) {

                                        mFriendsReqDatabase.child( mCuurentUser.getUid() ).child( user_id ).removeValue().addOnCompleteListener( new OnCompleteListener<Void>() {
                                            @Override
                                            public void onComplete(@NonNull Task<Void> task) {
                                                if (task.isSuccessful()) {
                                                    mFriendsReqDatabase.child( user_id ).child( mCuurentUser.getUid() ).removeValue().addOnCompleteListener( new OnCompleteListener<Void>() {
                                                        @Override
                                                        public void onComplete(@NonNull Task<Void> task) {
                                                            if (task.isSuccessful()) {
                                                                mDialog.dismiss();
                                                                mCuurent_state = "friends";
                                                                mProfileSendReqBtn.setText( "Unfriend This Person" );
                                                                mProfileSendReqBtn.setBackgroundColor( getResources().getColor( R.color.colorAccent ) );

                                                                mProfileDeclineReqBtn.setVisibility( View.INVISIBLE );
                                                                mProfileDeclineReqBtn.setEnabled( false );

                                                                showSuccess( "Success approve friend request!" );
                                                            } else {
                                                                mDialog.dismiss();
                                                                onError( "Failed approve friend request!" );
                                                            }
                                                        }
                                                    } );
                                                } else {
                                                    mDialog.dismiss();
                                                    onError( "Failed approve friend request!" );
                                                }
                                                mProfileSendReqBtn.setEnabled( true );
                                            }
                                        } );

                                    }
                                } );
                            } else {
                                mDialog.dismiss();
                                onError( "Failed approve friend request!" );
                            }
                            mProfileSendReqBtn.setEnabled( true );
                        }
                    } );
                }

                // ========== ACTION REMOVE FRIENDS ==========
                if (mCuurent_state.equals( "friends" )) {
                    showLoading( "Data is processing...!" );
                    mFriendsDatabase.child( mCuurentUser.getUid() ).child( user_id ).removeValue().addOnSuccessListener( new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void aVoid) {
                            mDialog.dismiss();
                            mCuurent_state = "not_friends";
                            mProfileSendReqBtn.setText( "Send Friend Request" );
                            mProfileSendReqBtn.setBackgroundColor( getResources().getColor( R.color.successAlert ) );
                        }
                    } );
                }

            }
        } );

    }

    private void showLoading(String s) {
        mDialog.setTitle( "Please wait a moment" );
        mDialog.setMessage( s );
        mDialog.setCanceledOnTouchOutside( false );
        mDialog.show();
    }

    public void showSuccess(String message) {
        Alerter.create( this )
                .setTitle( "Success" )
                .setText( message )
                .setBackgroundColorRes( R.color.successAlert )
                .show();
    }
}

MyFirebaseMessagingService.java

package com.bertho.chat;


import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FCM Service";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived( remoteMessage );

        String notificationTitle = remoteMessage.getNotification().getTitle();
        String notificationBody = remoteMessage.getNotification().getBody();

        String click_action = remoteMessage.getNotification().getClickAction();

        String from_user_id = remoteMessage.getData().get( "from_user_id" );

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder( this )
                        .setSmallIcon( R.drawable.notif_icon )
                        .setContentTitle( notificationTitle )
                        .setContentText( notificationBody );

        Intent resultIntent = new Intent(click_action);
        resultIntent.putExtra( "user_id",  from_user_id);

        PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        resultIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);


        int mNotificationId = (int) System.currentTimeMillis();

        NotificationManager mNotifyMgr =
                (NotificationManager) getSystemService( NOTIFICATION_SERVICE );
        mNotifyMgr.notify( mNotificationId, mBuilder.build() );

    }
}

According to the description the error log refers to this line

mUserDatabase = FirebaseDatabase.getInstance().getReference().child( "Users" ).child( user_id );

Is in this case an application unable to load data from the Firebase database so that it becomes crashed?

Please advise

Upvotes: 2

Views: 1019

Answers (2)

Bertho Joris
Bertho Joris

Reputation: 1601

I change my Firebase Function from

const payload = {
    notification: {
        title: "New Friend Request",
        body: `${userName} has sent you Friend Request`,
        icon: "default",
        click_action: "com.bertho.chat_TARGET_NOTIFICATION"
    },
    data: {
        from_user_id: from_user_id
    }
};

to

const payload = {
    data: {
        title: "New Friend Request",
        body: `${userName} has sent you Friend Request`,
        from_user_id: from_user_id,
        click_action: "com.bertho.chat_TARGET_NOTIFICATION"
    }
};

Thanks to @UmarZaii

Upvotes: 1

UmarZaii
UmarZaii

Reputation: 1351

1ST SOLUTION:

If you want to prevent the crash from happening, you can change the code from ProfileActivity.java

final String user_id = getIntent().getStringExtra( "user_id" );

To this code.

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
final String user_id;
if (getIntent().getStringExtra( "user_id" ).equals("") ||
        getIntent().getStringExtra( "user_id" ) == null) {
    user_id = getIntent().getStringExtra( "user_id" );
} else if (firebaseAuth.getCurrentUser() != null) {
    user_id = firebaseAuth.getCurrentUser().getUid();
} else {
    //There is no active user and the userID retrieved is null
}

As you can see, the if else statement checks whether the user_id that you retrieved from the notification is null or empty.

If it is then it will checks the current user that logged in to the application and use the user_id that retrieved by FirebaseAuth.

If both of them is empty or null then inform to me. I will update my answer.

2ND SOLUTION:

Don't use String from_user_id = remoteMessage.getData().get( "from_user_id" ); this code in your MyFirebaseMessagingService.java. Instead use below code.

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    FirebaseAuth firebaseAuth;

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived( remoteMessage );

        firebaseAuth = FirebaseAuth.getInstance();
        String from_user_id = firebaseAuth.getCurrentUser().getUid();
    }
}

I hope it helps. Feel free to ask me if it didn't work.

Upvotes: 0

Related Questions