-1

Guys i have been making this simple Uber app and whenever the Driver LogsOut my app crashes because the getCurrentUser() method is returning a null value. But whenever the user logsOut im closing the activity, and before calling getCurrentUser() i have this if(getApplicationContext()!=null) which should return false because the activity is closed so it should prevent getCurrentUser() from being called. How do i prevent it from crashing? What am i missing here?

This is where on Button click i logOut my user

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//some code here

    mLogout=(Button)findViewById(R.id.logout);
            mLogout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    isLoggingOut = true;
                    disconnectDriver();
                    
                    //Signing out user here
                    FirebaseAuth.getInstance().signOut();
                    Intent intent = new Intent(DriverMapActivity.this, MainActivity.class);
                    startActivity(intent);
                    return;
                }
            });
//some code here
}

This is where the error is happening

@Override
    //this is going to run whenever the driver location changes
    public void onLocationChanged(Location location) {
        if(getApplicationContext()!=null) {

            mLastLocation = location;
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
          
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

            //
            //This is where the error is happening
            //java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
            
            String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
            
            DatabaseReference refAvailable = FirebaseDatabase.getInstance().getReference("driversAvailable");
            
            DatabaseReference refWorking  = FirebaseDatabase.getInstance().getReference("driversWorking");
            
            GeoFire geoFireAvailable = new GeoFire(refAvailable);
           
            GeoFire geoFireWorking = new GeoFire(refWorking);
      
            switch(customerId){
               
                case "":

                   geoFireWorking.removeLocation(userId);
                    geoFireAvailable.setLocation(userId, new GeoLocation(location.getLatitude(), location.getLongitude()));
                    break;
                default:

                   
                    geoFireAvailable.removeLocation(userId);
                    geoFireWorking.setLocation(userId, new GeoLocation(location.getLatitude(), location.getLongitude()));
                    break;

            }
        }
    }

This is the Error Log

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.jonanako.uber, PID: 15522
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
        at com.jonanako.uber.DriverMapActivity.onLocationChanged(DriverMapActivity.java:211)
        at com.google.android.gms.internal.location.zzat.notifyListener(com.google.android.gms:play-services-location@@18.0.0:2)
        at com.google.android.gms.common.api.internal.ListenerHolder.zaa(com.google.android.gms:play-services-base@@18.0.1:2)
        at com.google.android.gms.common.api.internal.zacb.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
bombo klat
  • 41
  • 4
  • it should've not crashed because whenever you signout you are checking for if(getApplicationContext()!=null) but I don't know – JOWMIND Jan 27 '22 at 19:47
  • It is not crashing because getUid() returns null, but because getCurrentUser() returns null. User has logged out, there is no current user, why do you expect you can safely use getCurrentUser afterward? – Dalija Prasnikar Jan 27 '22 at 19:50
  • @Dalija Prasnikar No it does not, you pointed me to a vague answer – bombo klat Jan 27 '22 at 19:51
  • @Dalija Prasnikar (getApplicationContext()!=null) whenever the user signs out the activity is closed so before calling getCurrentUser im checking if the activity is not null – bombo klat Jan 27 '22 at 19:54
  • First, getApplicationContext() is whole application context, not activity context. Besides, it is not crashing there it crashes because getUid() is called on null reference which means getCurrentUser() returns null. It is written in the log. – Dalija Prasnikar Jan 27 '22 at 20:00
  • @Dalija Prasnikar yes getCurrentUser() returns null because on button click this function appFirebaseAuth.getInstance().signOut(); is called which disconnects the user and after disconnecting the user we open a new activity Intent intent = new Intent(DriverMapActivity.this, MainActivity.class); startActivity(intent); so the app must not call this function onLocationChanged() because the activity is closed, but its still calling it :( – bombo klat Jan 27 '22 at 20:08
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241467/discussion-between-bombo-klat-and-dalija-prasnikar). – bombo klat Jan 27 '22 at 20:10
  • It appears you are leaving an observer in place. Observers will continue to observe until you actually remove the observer. – Jay Jan 27 '22 at 20:19

2 Answers2

1

getApplicationContext() won't be null when you finish() Activity, even last or one and only. consider using if(!isFinishing()), lifecycle checking or just set own boolean flag.

additionally you may (should) also check that getCurrentUser() returns null, that would mean that user logs out. if is null then don't call any method on returned object (because nothing is returned in fact)

if(!isFinishing() && FirebaseAuth.getInstance().getCurrentUser()!=null) {
snachmsm
  • 17,866
  • 3
  • 32
  • 74
1

Since you assign false to your isLoggingOut = true; whenever you click on the button, you should just check if(getApplicationContext()!=null && !isLoggingOut) so the code wont run whenever isLoggingOut==false;

JOWMIND
  • 91
  • 7
  • `getApplicationContext()` won't never return `null` in this case, thus this `if` may be shortened to `if(!isLoggingOut)`. personally I would still check `getCurrentUser()` returns non-`null` value – snachmsm Jan 27 '22 at 21:31
  • @bomboklat the only issue with this answer is that if the app crashes or has some other issue the state of the vars can be unknown - so relying on isLoggedOut could be intermittent. Best practice is to rely on Firebase to tell you if a user is authenticated or not. Also, please remember that Firebase calls are asynchronous to code directly following a function may occur *before* the function completed. It's best to execute code within the closure following the firebase function to ensure it completes before the code is called. – Jay Jan 28 '22 at 16:49